poj 3259 Wormholes
bellman算法
John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。
--------------------------------------------------------------------
#include <iostream> #include <math.h> #include <algorithm> #include <cstdio> #include <cstring> #define MAXN 520 #define MAXM 6000 #define INF 0Xffffff using namespace std ; struct node { int u, v, w; } edge[MAXM]; int T, n, m, l, u, v, w; int dis[MAXN], ans; int bellman() { for(int i=0; i<n; i++) dis[i] = INF; ///可以写成fill(dis,did+n,INF); dis[1] = 0; for(int i=0; i<n; i++) { int flag = 0; for(int j=0; j<ans; j++) { if(dis[edge[j].u]>dis[edge[j].v]+edge[j].w)///松弛 { dis[edge[j].u]=dis[edge[j].v]+edge[j].w; flag = 1; } } if(!flag) break; ///因为对于V个点 你最多需要进行|V|-1次外循环,如果有负环它会一直进行下去, ///但是只要进行到第V次的时候就说明存在负环了 if(i==n-1)///如果存在负边 return 1; } return 0; } void add(int u,int v,int w) { edge[ans].u = u; edge[ans].v = v; edge[ans].w = w; ans++; } int main() { scanf("%d", &T); while(T--) { ans = 0; scanf("%d %d %d", &n, &m, &l); for(int i=0; i<m; i++) { scanf("%d %d %d", &u, &v, &w); add(u, v, w); add(v, u, w); } for(int i=0; i<l; i++) { scanf("%d %d %d", &u, &v, &w); add(u, v, -w); } if(!bellman()) printf("NO\n"); else printf("YES\n"); } return 0; }