题目链接。
分析:
本题的关键的关键是——看懂题。。。
本质就是求该图是否存在负环。也就是如何求出一个图是否含有负环。
要注意的是输入该题中的path是双向的,wormhole是单向的。
Bellman_Ford:
View Code
1 #include <stdio.h> 2 3 #define MAXN 520 4 #define MAXM 6000 5 6 const int INF = (1<<26); 7 8 struct node{ 9 int u, v, w; 10 }edge[MAXM]; 11 12 int dis[MAXN], top; 13 14 int bellman_ford(int n){ 15 int i, j, u, v, w; 16 17 for(i=1; i<=n; i++) dis[i] = INF; 18 dis[1] = 0; 19 for(i=0; i<n-1; i++){ 20 for(j=0; j<top; j++){ 21 u = edge[j].u; 22 v = edge[j].v; 23 w = edge[j].w; 24 if(dis[u] < INF && dis[u]+w < dis[v]){ 25 dis[v] = dis[u]+w; 26 } 27 } 28 } 29 30 for(j=0; j<top; j++){ 31 u = edge[j].u; 32 v = edge[j].v; 33 w = edge[j].w; 34 if(dis[u] < INF && dis[u]+w < dis[v]){ 35 return 0; 36 } 37 } 38 return 1; 39 } 40 41 void add(int u, int v, int w){ 42 edge[top].u = u; 43 edge[top].v = v; 44 edge[top++].w = w; 45 } 46 47 int main(){ 48 int T, n, m, l, i, u, v, w; 49 50 scanf("%d", &T); 51 while(T--){ 52 top = 0; 53 scanf("%d %d %d", &n, &m, &l); 54 for(i=0; i<m; i++){ 55 scanf("%d %d %d", &u, &v, &w); 56 add(u, v, w); 57 add(v, u, w); 58 } 59 for(i=0; i<l; i++){ 60 scanf("%d %d %d", &u, &v, &w); 61 add(u, v, -w); 62 } 63 if(!bellman_ford(n)) printf("YES\n"); 64 else printf("NO\n"); 65 } 66 67 return 0; 68 }
SPFA:
View Code
1 #include <cstdio> 2 #include <queue> 3 4 using namespace std; 5 6 #define MAXN 520 7 #define MAXM 6000 8 9 const int INF = (1<<26); 10 11 struct node{ 12 int v, w; 13 int next; 14 }edge[MAXM]; 15 16 queue<int> q; 17 int dis[MAXN], head[MAXN], top, inq[MAXN], used[MAXN]; 18 19 20 void add(int u, int v, int w){ 21 edge[top].v = v; 22 edge[top].w = w; 23 edge[top].next = head[u]; 24 head[u] = top++; 25 } 26 27 int spfa(int n){ 28 for(int i=1; i<=n; i++) dis[i] = INF; 29 dis[1] = 0; 30 q.push(1); 31 used[1]++; 32 while(!q.empty()){ 33 int x = q.front(); q.pop(); 34 inq[x] = 0; 35 for(int u = head[x]; u != -1; u = edge[u].next){ 36 if(dis[edge[u].v] > dis[x]+edge[u].w){ 37 dis[edge[u].v] = dis[x]+edge[u].w; 38 if(!inq[edge[u].v]){ 39 inq[edge[u].v] = 1; 40 if(++used[edge[u].v] > n-1) return 0; 41 q.push(edge[u].v); 42 } 43 } 44 } 45 } 46 return 1; 47 } 48 49 void Init(int n){ 50 top = 0; 51 for(int i=1; i<=n; i++){ 52 inq[i] = 0; 53 used[i] = 0; 54 head[i] = -1; 55 } 56 } 57 58 int main(){ 59 int T, n, m, l, i, u, v, w; 60 61 scanf("%d", &T); 62 63 while(T--){ 64 scanf("%d %d %d", &n, &m, &l); 65 66 Init(n); 67 68 for(i=0; i<m; i++){ 69 scanf("%d %d %d", &u, &v, &w); 70 add(u, v, w); 71 add(v, u, w); 72 } 73 for(i=0; i<l; i++){ 74 scanf("%d %d %d", &u, &v, &w); 75 add(u, v, -w); 76 } 77 78 if(!spfa(n)) printf("YES\n"); 79 else printf("NO\n"); 80 } 81 82 return 0; 83 }