[USACO06DEC]虫洞Wormholes (负环模板)
Posted sj-gank
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO06DEC]虫洞Wormholes (负环模板)相关的知识,希望对你有一定的参考价值。
题意::问一个图是否存在负环,虫洞一边的权值为负
思路:
dfs版spfa判环根据:若一个节点出现2次及以上,则存在负环.(你可以假想一下,当一个点被搜过时,再次深搜的话还能搜索到那不就说明存在负环嘛可能解释的不好,请见谅)
{补充bfs版本:若一个节点入队列的次数超过n,则存在负环.}
如果是bfs来实现的话,果断到达上限(T-L-E),而dfs版的话,就相对快一些.
对于本题的强大数据来说,还需加入一定的优化:
由于是负环,所以无需像一般的spfa一样初始化为极大的数,只需要初始化为0就够了(可以减少大量的搜索,但要注意最开始时for一遍)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=505; 5 int inf=0xfffffff; 6 int dis[maxn]; 7 bool ant[maxn]; 8 int n,m,w,flag; 9 struct node 10 11 int to,val; 12 node() 13 node(int xx,int yy):to(xx),val(yy) 14 ; 15 vector<node> v[maxn];//本人喜欢用邻接表 16 void init() 17 18 for(int i=1;i<=n;i++) 19 20 v[i].clear(); 21 dis[i]=0; 22 ant[i]=0; 23 24 25 void dfs_spfa(int x) 26 27 if(ant[x])//只要有一个点走过两次说明存在负环,即可退出,并释放标记 28 ant[x]=0; 29 flag=1; 30 return ; 31 32 ant[x]=1;//标记表示走过 33 for(int i=0;i<v[x].size();i++) 34 35 node p=v[x][i]; 36 if(dis[p.to]>dis[x]+p.val) 37 dis[p.to]=dis[x]+p.val; 38 dfs_spfa(p.to); 39 if(flag==1) 40 ant[x]=0;return ;//存在负环的话就层层退出 41 42 43 44 ant[x]=0;//再次释放标记 45 46 int main() 47 48 int t; 49 scanf("%d",&t); 50 while(t--) 51 52 scanf("%d%d%d",&n,&m,&w); 53 init(); 54 for(int i=1;i<=m;i++) 55 56 int a,b,c; 57 scanf("%d%d%d",&a,&b,&c); 58 v[a].push_back(node(b,c)); 59 v[b].push_back(node(a,c)); 60 61 for(int i=1;i<=w;i++) 62 63 int a,b,c; 64 scanf("%d%d%d",&a,&b,&c); 65 v[a].push_back(node(b,-c)); 66 67 flag=0; 68 for(int i=1;i<=n;i++) 69 70 dfs_spfa(i); 71 if(flag)break; 72 73 if(flag) 74 cout<<"YES"<<endl; 75 76 else 77 cout<<"NO"<<endl; 78 79 80 return 0; 81
留给自己做模板用5555
以上是关于[USACO06DEC]虫洞Wormholes (负环模板)的主要内容,如果未能解决你的问题,请参考以下文章
[USACO06DEC]虫洞Wormholes (负环模板)
[BZOJ1715][Usaco2006 Dec]Wormholes 虫洞
bzoj1715[Usaco2006 Dec]Wormholes 虫洞*