负环 https://www.luogu.com.cn/problem/P3385
-
使用BFS的SPFA算法和普通的SPFA没有什么区别,我们如何判断有没有负环呢?我们有两种判法.
-
1.记录此点被更新了多少次,更新次数大于N就有负环.这意味着一个点被重复迭代超过N次,显然有负环.
-
2.记录从S到当前点路径上经过了多少个点,超过N则有负环.这张图才有N个点,一条路径上没有重复点经过点数是<= N的,所以有负环.
用 t[ ] 表示被迭代多少次
1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 5 #define M 6010 6 #define N 2010 7 #define clear(a) memset(a,0,sizeof(a)) 8 9 using namespace std; 10 11 int dis[N],t[N]; 12 bool vis[N]; 13 int n,m,x,y,z,tot; 14 int hd[M]; 15 struct node{ 16 int ver,nxt,w; 17 }e[M]; 18 queue<int> q; 19 20 void add(int x,int y,int z){ 21 e[++tot].ver=y,e[tot].w=z,e[tot].nxt=hd[x],hd[x]=tot; 22 } 23 24 bool spfa(){ 25 memset(dis,0x3f,sizeof(dis)); 26 memset(vis,false,sizeof(vis)); 27 memset(t,0,sizeof(t)); 28 while(!q.empty()) q.pop(); 29 dis[1]=0;vis[1]=1;t[1]=1; 30 q.push(1); 31 while(q.size()){ 32 int x=q.front();q.pop(); 33 vis[x]=0; 34 for(int i=hd[x];i;i=e[i].nxt){ 35 int y=e[i].ver,z=e[i].w; 36 if(dis[y]>dis[x]+z){ 37 dis[y]=dis[x]+z; 38 if(++t[y]>n) return 1; 39 if(!vis[y]) q.push(y),vis[y]=1; 40 } 41 } 42 } 43 return 0; 44 } 45 46 int main() 47 { 48 int T; 49 cin>>T; 50 while(T--) 51 { 52 tot=0;memset(hd,0,sizeof(hd)); 53 cin>>n>>m; 54 for(int i=1;i<=m;i++) 55 { 56 cin>>x>>y>>z; 57 if(z<0) add(x,y,z); 58 else add(x,y,z),add(y,x,z); 59 } 60 if(spfa()) cout<<"YE5"<<endl;//坑!!! 61 else cout<<"N0"<<endl; 62 } 63 return 0; 64 }