bzoj4773 负环

Description
在忘记考虑负环之后,黎瑟的算法又出错了。对于边带权的有向图 G = (V, E),请找出一个点数最小的环,使得
环上的边权和为负数。保证图中不包含重边和自环。

Input
第1两个整数n, m,表示图的点数和边数。
接下来的m行,每<=三个整数ui, vi, wi,表<=有一条从ui到vi,权值为wi的有向边。
2 <= n <= 300
0 <= m <= n(n <= 1)
1 <= ui, vi <= n
|wi| <= 10^4

Output
仅一行一个整数,表示点数最小的环上的点数,若图中不存在负环输出0。

Sample Input
3 6
1 2 -2
2 1 1
2 3 -10
3 2 10
3 1 -10
1 3 10

Sample Output
2

分析:
求负环:
A:bellmax ford
B:floyed
C:spfa(扔下去。。。)

设计状态
f[k][i][j]表示i到j经过k个点的最短路
枚举k和i,
如果存在f[k][i][i]是负数, 那么就是一个负环
k可以通过倍增得到:f[k]<—f[k-1],f[k-1]
这只是基本原理
具体实现有一些细节

其实我们需要进行两次floyed
第一次利用倍增的方法
维护好f[k][i][j]
f[k][i][j]=min(f[k-1][i][l]+f[k-1][l][j]);

但是这样的话我们只知道走2^k步时的答案
想想第一次接触倍增是什么时候
没错,LCA
那时候我们是怎么处理的呢
for (i=lg;i>=0;i–)
这就相当于把答案二进制分解了
得出的答案+1就是最终答案

这道题也是一样

我们要求的是不存在负环的最大步数,

最大步数+1即为答案

第一次floyed我们得到了一个k(走2^k出现负环)
那答案一定<=2^k
我们就把k从大到小循环
只要是f[k][i][i]>0
ans+=(1 << k)

当然还有一些细节要处理
还记得我们一开始记录了一个h邻接矩阵
在循环的开始
我们先调用一个全新的函数:memecpy(a,b,sizeof(b))
表示b中的信息全部复制到a

这个while循环我们可以一步一步看
首先memcpy,g保存一下h数组的信息
设g记录了走x步时的floyed的答案
之后就进行了一次耳熟能详的floyed
用来判断在走2^k+x步数的情况下
能不能走出负环,

能:把h数组的信息还原(这个2^k+x太大了,不符合我们找最大非负环的限制)

不能:ans+=(1 << k),h数组中的信息保留(走2^k+x)

这个h/g数组就相当于记录没有负环的最大步数

ans记录走了多少步

最后输出ans+1

tip

变量名不要搞错了

这里写代码片
#include<cstdio>
#include<iostream>
#include<cstring>using namespace std;const int N=310;
const int lg=10;
int n,m,f[lg][N][N],g[N][N],h[N][N],ans;void floyed()
{int i,j,k,l;for (k=1;k<lg;k++){bool ff=0;for (l=1;l<=n;l++)  //最外层循环折点 for (i=1;i<=n;i++)for (j=1;j<=n;j++){f[k][i][j]=min(f[k][i][j],f[k-1][i][l]+f[k-1][l][j]);}for (i=1;i<=n;i++)if (f[k][i][i]<0) ff=1;if (ff) break;if ((1<<k)>=n)  //整张图都不存在负环 {puts("0");return;}}ans=0;while (k>=0)  //步数{memcpy(g,h,sizeof(h));bool ff=0;for (l=1;l<=n;l++)for (i=1;i<=n;i++)for (j=1;j<=n;j++)h[i][j]=min(h[i][j],g[i][l]+f[k][l][j]);for (i=1;i<=n;i++)if (h[i][i]<0) ff=1;if (ff) memcpy(h,g,sizeof(g));  //恢复信息 else ans+=(1<<k);k--;} printf("%d",ans+1);
}int main()
{scanf("%d%d",&n,&m);memset(f,0x33,sizeof(f));memset(h,0x33,sizeof(h));for (int i=1;i<=n;i++) f[0][i][i]=h[i][i]=0;   //h邻接矩阵 for (int i=1;i<=m;i++) {int u,w,z;scanf("%d%d%d",&u,&w,&z);f[0][u][w]=z;}floyed();return 0;
}

转载于:https://www.cnblogs.com/wutongtong3117/p/7673380.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/268555.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工业无线遥控器 SUNRF-1011RC

工业无线遥控器 SUNRF-1011RC工业无线遥控器产品 授权操作 一&#xff1a;简介&#xff1a;工业无线遥控器&#xff0c;是针对工业环境&#xff0c;专门设计的无线控制替代有线控制的方案。和有线控制一样&#xff0c;具有实时性、灵活性、多路同时操作、操作灵活顺畅无…

C语言封装带省略参数的函数,C与C++的函数声明中省略参数的不同意义

一直都以为C/C中形如int func();这样的函数声明其意义就是一个参数 void(没有参数)的函数。然而今天在看C的时候突然看到这么一句&#xff1a;对于带空参数表的函数&#xff0c;C和C有很大的不同。在C语言中&#xff0c;声明int func2();表示“一个可带任意参数(任意数目&#…

常见的CSS和HTML面试题

1. 常用那几种浏览器测试&#xff1f;有哪些内核(Layout Engine)? 浏览器&#xff1a;IE&#xff0c;Chrome&#xff0c;FireFox&#xff0c;Safari&#xff0c;Opera。 内核&#xff1a;Trident&#xff0c;Gecko&#xff0c;Presto&#xff0c;Webkit。 2. 说下行内元素和块…

理解快速生成树协议(RSTP)(二)

RSTP引进了新的BPDU处理以及一种新的拓扑结构改变机制。即使没有从根桥处接收到任何信号&#xff0c;每个网桥在每次“hello时间周期中”中都生成BPDU。BPDU扮演了在网桥间进行消息通知的角色。如果一个网桥不能从临近网桥处收到BPDU&#xff0c;它就会认为与这个网桥失去了连接…

C语言位运算

一、位运算符&#xff23;语言提供了六种位运算符&#xff1a;& 按位与| 按位或^ 按位异或~ 取反<< 左移>> 右移1. 按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时&#xff0…

c语言运行后没生成exe,这个程序怎么运行?为什么显示没有exe??

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include #include #include #include void main(){void welcome();void over(int x);void state();void score(int x);void hp(int x);welcome();state();char key;int x, y,a,m;int sc 0,wc 0;srand(time(NU…

网络工程师之广域网必胜篇一

完全没有必要看网工的教程&#xff0c;仔细阅读完以下篇幅&#xff0c;基本上能够应付网工的考试了&#xff0c;注意&#xff0c;一定要是仔细阅读。<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />广域网广域网&#xff08;WAN…

POJ2243 Knight Moves —— A*算法

题目链接&#xff1a;http://poj.org/problem?id2243 Knight MovesTime Limit: 1000MS Memory Limit: 65536KTotal Submissions: 14500 Accepted: 8108Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the short…

c语言多重括号,大佬在吗,我用C写了一个去多重括号的函数,结果。。。

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include "malloc.h"char * changeOrder(char *s);struct Node{char *data;struct Node * link;};struct Node * top1 NULL;struct Node * top2 NULL;void Push1(char *s){struct Node * temp (str…

mac配置telnet

/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" brew install telnet

linux下的DNS服务器详解

DNS&#xff1a;Domain Name System 域名管理系统 域名是由圆点分开一串单词或缩写组成的&#xff0c;每一个域名都对应一个惟一的IP地址&#xff0c;这一命名的方法或这样管理域名的系统叫做域名管理系统。 大家都知道&#xff0c;当我们在上网的时候&#xff0c;通常输入的是…

c语言一个循环重新输入密码,想程序高手求助--用C语言来编辑一个输入密码的程序...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*--------实现密码的隐式输入-----------------*/inputpw(char *password,int len) /*len为密码长度*/{int i0; /*密码数组索引值,同时也表示记录已显示*的数目*/char ch;fflush(stdin); /*清洗流&#xff0c;以防妨碍密码正确输入…

怎样玩转千万级别的数据

作者&#xff1a;Sam Xiaowww.cnblogs.com/xcj26/p/3305789.html如有好文章投稿&#xff0c;请点击 → 这里了解详情大数据处理是一个头疼的问题&#xff0c;特别当达不到专业DBA的技术水准时&#xff0c;对一些数据库方面的问题感到无奈。所以还是有必要了解一些数据库方面的技…

c语言多维数组基础知识,C语言基础第7章多维数组.ppt

C语言基础第7章多维数组7.2 二维数组及多维数组二维数组的定义定义方式&#xff1a;  数据类型 数组名[常量表达式][常量表达式]&#xff1b;;二维数组理解;二维数组元素的引用形式&#xff1a; 数组名[下标][下标]二维数组元素的初始化分行初始化&#xff1a;;程序举例;例 …

关于待机、休眠、睡眠的区别和优缺点

Windows中很早就加入了待机、休眠等模式&#xff0c;而Windows Vista中更是新加入了一种叫做睡眠的模式&#xff0c;可是很多人还是习惯在不使用电脑的时候 将其彻底关闭。其实充分利用这些模式&#xff0c;我们不仅可以节约电力消耗&#xff0c;还可以用尽可能短的时间把系统恢…