SPFA判一下是否存在负环即可。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int INF=0x7FFFFFFF; const int maxn=500+10; int n,m,w; int g[maxn][maxn]; int dis[maxn],flag[maxn],tot[maxn]; bool fail; void SPFA() { queue<int>Q; for(int i=1; i<=n; i++) dis[i]=INF,flag[i]=0,tot[i]=0;; flag[1]=1; Q.push(1); dis[1]=0; while(!Q.empty()) { int head=Q.front(); Q.pop(); flag[head]=0; tot[head]++; if(tot[head]>=n) { fail=1; break; } for(int k=1; k<=n; k++) { if(g[head][k]==INF||k==head) continue; if(dis[head]+g[head][k]<dis[k]) { dis[k]=dis[head]+g[head][k]; if(flag[k]==0) { Q.push(k); flag[k]=1; } } } } } int main() { int F; scanf("%d",&F); while(F--) { fail=0; scanf("%d%d%d",&n,&m,&w); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) g[i][j]=INF; for(int i=1; i<=m; i++) { int S,E,T; scanf("%d%d%d",&S,&E,&T); g[S][E]=g[E][S]=min(g[E][S],T); } for(int i=1; i<=w; i++) { int S,E,T; scanf("%d%d%d",&S,&E,&T); g[S][E]=min(g[S][E],-T); } SPFA(); if(fail) printf("YES "); else printf("NO "); } return 0; }