POJ3259 Wormholes(最短路)

题目链接

分析:

本题的关键的关键是——看懂题。。。

本质就是求该图是否存在负环。也就是如何求出一个图是否含有负环。

要注意的是输入该题中的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 }

 

posted on 2013-02-27 20:01  Still_Raining  阅读(2218)  评论(0)    收藏  举报