题目大意:有F组数据,N表示有N点,M表示有M条边,走一遍边需要花费Ti个时间,还有W个虫洞,可以向前回溯Ti时间,求能否从1点出发,经过一些路或虫洞回到1点后时间为负。
建图后用SPFA判负环即可。
code:
#include <cstdio> #include <cstring> using namespace std; int read() { char c;while(c=getchar(),c<'0'||c>'9'); int x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0'; return x; } int T; int N,M,W; int x,y,c; struct list{ int head[505],nxt[10000],To[10000],W[10000],cnt; void fc(){memset(head,-1,sizeof head);memset(nxt,-1,sizeof nxt);cnt=0;} void add(int x,int y,int c) { W[cnt]=c;To[cnt]=y; nxt[cnt]=head[x]; head[x]=cnt; cnt++; } }MP; bool flag; int dist[505],vis[505]; void SPFA(int now) { if(flag)return ; vis[now]=1; for(int i=MP.head[now];i!=-1;i=MP.nxt[i]){ if(dist[now]+MP.W[i]<dist[MP.To[i]]){ if(vis[MP.To[i]]){flag=true;return ;} dist[MP.To[i]]=dist[now]+MP.W[i]; vis[MP.To[i]]=1;SPFA(MP.To[i]); } } vis[now]=0; return ; } int main() { T=read(); register int i,j; while(T--){ N=read(),M=read(),W=read(); MP.fc(); for(i=1;i<=M;i++){ x=read(),y=read(),c=read(); MP.add(x,y,c); MP.add(y,x,c); } for(i=1;i<=W;i++){ x=read(),y=read(),c=read(); MP.add(x,y,-c); } memset(vis,0,sizeof vis);memset(dist,63,sizeof dist);dist[1]=0; flag=0;SPFA(1); if(flag)puts("YES"); else puts("NO"); } }