题目链接:http://poj.org/problem?id=3259
题意:现在有n个点,m条边,w个虫洞,给出m个a,b,c,表示从a到b需要花费c时间,从b到a需要话费c时间,然后给出w个a,b,c,表示从a到b花费-c个时间,问是否存在一条路径使得最终回到源点的时间比初始时间小。
思路:最短路径,Bellman-Ford或SPFA判断是否存在负环的问题。
注意:数据范围比题目中给的略大一点,这点略坑。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int maxn=1010; int T,n,m,w; int dis[maxn]; int eNum; struct Edge{ int s; int e; int t; }edge[10000]; void addEdge(int s,int e,int t){ edge[eNum].s=s; edge[eNum].e=e; edge[eNum].t=t; eNum++; } bool Bellman_Ford(){ for(int i=1;i<=n;i++) dis[i]=INF; dis[1]=0; for(int i=1;i<n;i++){ for(int j=0;j<eNum;j++){ if(dis[edge[j].e]>dis[edge[j].s]+edge[j].t){ dis[edge[j].e]=dis[edge[j].s]+edge[j].t; } } } for(int k=0;k<eNum;k++){ if(dis[edge[k].e]>dis[edge[k].s]+edge[k].t){ return true; } } return false; } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&w); eNum=0; int s,e,t; for(int i=0;i<m;i++){ scanf("%d%d%d",&s,&e,&t); addEdge(s,e,t); addEdge(e,s,t); } for(int i=0;i<w;i++){ scanf("%d%d%d",&s,&e,&t); addEdge(s,e,-t); } bool ans=Bellman_Ford(); if(ans) puts("YES"); else puts("NO"); } return 0; }