博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3385 【模板】负环 DFS-SPFA 判负环 图论
阅读量:7222 次
发布时间:2019-06-29

本文共 2194 字,大约阅读时间需要 7 分钟。

洛谷P3385 【模板】负环

图论

今天get了 一个 DFS-SPFA 判负环的方法

一般的 BFS-SPFA 判负环 一般就是 不停地做,如果某点第 n+1次加入队列中,那么说明这个图存在负环

然而我并不会证明,期望复杂度是 O(kM) k 大约是在 2 左右 但是其实对于一些极限数据,最坏可以
把他卡到 O( NM) 额,这就直接炸飞了是不是,而且据说,一些数据比较强的题目,总会想到卡一卡SPFA
的,

然后我们换一种思路

因为题目中一定存在一种 负环对吧,所以说假如你某段路径权值和为自然数的时候, 你这一段还不如
不走对不对,你还不如直接从第一条负边开始走起,
我们把每个点的 dist设为 0 ,dfs下去如果能够松弛的话就一直松弛下去,这时候的松弛还有另一个含义
,因为你设的每个的dist是 0 ,所以能够松弛还说明的到 从起点 s 到这个点的 路径和一直是 负的,
我们把在这条路径中的点标记一下,如果下次 有松弛过的点 到这个点,那么说明就有负环

另外 要注意从每一个点开始的 DFS-SPFA 求的只是求的 以他为起点的 负环是否存在,因为 每次dfs

如果碰到 不能松弛就不 松弛了,那么也许后面还能够松弛,所以说要枚举每一个点作为松弛起点
另外注意这题的坑点 YE'5' 和 N'0' 不包括引号
然后 注意一下初始化 边表 head 以及cnt 都要清空

 

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 using namespace std ; 10 11 const int maxn = 200011,maxm = 200011,inf = 1e9 ; 12 struct node{13 int to,val,pre ; 14 }e[2*maxm];15 int T,n,m,x,y,val,cnt ; 16 int head[maxn],dist[maxn] ; 17 bool flag ; 18 bool vis[maxn] ; 19 20 inline void addedge(int x,int y,int v) 21 {22 e[++cnt] = (node){ y,v,head[x] } ; 23 head[ x ] = cnt ; 24 }25 26 inline int read() 27 {28 char ch = getchar() ; 29 int x = 0 , f = 1 ; 30 while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 31 while(ch>='0'&&ch<='9') { x = x*10+ch-48 ; ch = getchar() ; } 32 return x*f ; 33 }34 35 inline void SPFA(int u) 36 {37 int v ; 38 vis[ u ] = 1 ; 39 for(int i=head[u];i;i = e[ i ].pre ) 40 {41 v = e[ i ].to ; 42 if( dist[ u ] + e[ i ].val < dist[ v ] ) 43 {44 dist[ v ] = dist[ u ] + e[ i ].val ; 45 if(vis[ v ]||flag) 46 {47 flag = 1 ; 48 break ; 49 }50 SPFA( v ) ; 51 }52 } 53 vis[ u ] = 0 ; 54 }55 56 int main() 57 {58 T = read() ; 59 while(T--) 60 {61 flag = 0 ; 62 cnt = 0 ; 63 n = read() ; m = read() ; 64 for(int i=1;i<=n;i++) dist[ i ] = 0,vis[ i ] = 0,head[ i ] = 0 ; //065 for(int i=1;i<=m;i++) 66 {67 scanf("%d%d%d",&x,&y,&val) ; 68 addedge(x,y,val) ; 69 if(val>=0) addedge(y,x,val) ; 70 }71 for(int i=1;i<=n;i++) 72 {73 SPFA( i ) ; 74 if(flag) break ; 75 } 76 if(flag) 77 printf("YE5\n") ; 78 else 79 printf("N0\n") ; 80 81 }82 return 0 ; 83 }

 

转载于:https://www.cnblogs.com/third2333/p/7029567.html

你可能感兴趣的文章
C# 对Excel操作时,单元格值的读取
查看>>
PreparedStatement--摘抄自http://blog.chinaunix.net/u/28512/showart_221625.html
查看>>
网络扫描程序的详细分析与实现
查看>>
SQL2005中时,Diagrams的问题
查看>>
每个分类取最新的几条的SQL实现
查看>>
智慧医疗“验血查癌”或会实现
查看>>
linux中时间精度的获取问题【转】
查看>>
Windows Workflow Foundation学习资源
查看>>
把字符串转化为类型
查看>>
Azure PowerShell (2) 修改Azure订阅名称
查看>>
ss命令使用示例
查看>>
http的请求和响应过程3
查看>>
借用Snippet插件美化博客中的代码
查看>>
Java:文件类File的详解
查看>>
watir学习--baidu搜索示例
查看>>
Hadoop Hive与Hbase关系 整合
查看>>
06.GitHub实战系列~6.过滤器过滤掉的文件如何上传
查看>>
HTML与XML总结
查看>>
ASP.NET 程序安全性 (一) web.config加密与解密
查看>>
计算机中的颜色XII——快速计算纯色的色相值(新的公式)
查看>>