普通的SPFA的负环判定。犯了三个错误,全部写在注释里了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 const int MAXNm=10000+500; 8 const int MAXNn=500+50; 9 const int INF=0x7fffffff; 10 int n,m,ww; 11 int u[MAXNm],v[MAXNm],w[MAXNm]; 12 int first[MAXNn],next[MAXNm]; 13 int dis[MAXNn]; 14 void addedge(int tu,int num) 15 { 16 next[num]=first[tu]; 17 first[tu]=num; 18 } 19 20 int SPFA() 21 { 22 queue<int> que; 23 int vis[MAXNn],appear[MAXNn]; 24 que.push(0); 25 for (int i=0;i<n;i++) 26 { 27 dis[i]=INF; 28 vis[i]=0; 29 appear[i]=0; 30 } 31 /*不要遗漏了上述初始化步骤*/ 32 dis[0]=0; 33 vis[0]=1; 34 appear[0]=1; 35 36 while (!que.empty()) 37 { 38 int head=que.front(); 39 que.pop(); 40 vis[head]=0; 41 /*注意这里vis[head]要重归于零!很容易错写成vis[k]=0*/ 42 int k=first[head]; 43 while (k!=-1) 44 { 45 if (dis[v[k]]>dis[u[k]]+w[k]) 46 { 47 dis[v[k]]=dis[u[k]]+w[k]; 48 if (!vis[v[k]]) 49 /*不要把vis[v[k]]写成vis[k]了*/ 50 { 51 appear[v[k]]++; 52 vis[v[k]]=1; 53 que.push(v[k]); 54 } 55 if (appear[v[k]]>=n) return 0; 56 } 57 k=next[k]; 58 } 59 } 60 return 1; 61 } 62 63 int main() 64 { 65 int c; 66 scanf("%d",&c); 67 for (int kase=0;kase<c;kase++) 68 { 69 scanf("%d%d%d",&n,&m,&ww); 70 for (int i=0;i<n;i++) first[i]=-1; 71 72 for (int i=0;i<m;i++) 73 { 74 scanf("%d%d%d",&u[i],&v[i],&w[i]); 75 u[i]--; 76 v[i]--; 77 addedge(u[i],i); 78 u[i+m]=v[i]; 79 v[i+m]=u[i]; 80 w[i+m]=w[i]; 81 addedge(u[i+m],i+m); 82 } 83 for (int i=2*m;i<2*m+ww;i++) 84 { 85 scanf("%d%d%d",&u[i],&v[i],&w[i]); 86 u[i]--; 87 v[i]--; 88 w[i]=-w[i]; 89 addedge(u[i],i); 90 } 91 if (!SPFA()) cout<<"YES";else cout<<"NO";cout<<endl; 92 } 93 94 return 0; 95 }
时间: 2024-10-07 06:47:34