POJ 3259 (bellman_ford)
虫洞!
注意两点:
1、路径是双向的,洞是单向的;
2、路径时间是正的,洞的时间是负的。
纯净的bellman_ford.
代码:
1 #include<iostream>
2 #include<cstdio>
3 using namespace std;
4 const int MAX = 0x7fffffff;
5
6 typedef struct node
7 {
8 int from,to,tim;
9 } Edge;
10
11 Edge e[5300];
12 int dis[501];
13 int filed,bidi,worm;
14 bool bellman_ford();
15
16 int main()
17 {
18 int T,i,j,a,b,t;
19 scanf("%d",&T);
20
21 do
22 {
23 scanf("%d%d%d",&filed,&bidi,&worm);
24 for(j = 1,i = 1 ; i <= bidi ; ++i)//路是双向的
25 {
26 scanf("%d%d%d",&a,&b,&t);
27 e[j].from = a;
28 e[j].to = b;
29 e[j++].tim = t;
30 e[j].from = b;
31 e[j].to = a;
32 e[j++].tim = t;
33 }
34 for(i = 1 ; i <= worm ; ++i)//虫洞是单向的
35 {
36 scanf("%d%d%d",&a,&b,&t);
37 e[j].from = a;
38 e[j].to = b;
39 e[j++].tim = -t;
40 }
41
42 if(bellman_ford())
43 printf("YES\n");
44 else
45 printf("NO\n");
46 }while(--T);
47
48 system("pause");
49 return 0;
50 }
51
52 bool bellman_ford()
53 {
54 int u,v,i,j,total,temp;
55 bool flag;
56 total = bidi*2 + worm;
57 for(i = 2 ; i <= filed ; ++i)
58 dis[i] = MAX;
59 /*
60 把第一个filed当起点,为什么呢?其他的可以当起点吗?
61 我试了第二个,最后一个等等,发现都可以AC。
62 但我不能肯定是否所有点都可以当做起点,
63 希望路过的大牛给予指点。
64 */
65 dis[1] = 0;
66
67 for(i = 1 ; i <= filed ; ++i)
68 {
69 flag = false;
70 for(j = 1 ; j <= total ; ++j)
71 {
72 u = e[j].from;
73 v = e[j].to;
74
75 temp = dis[u] + e[j].tim;
76 if(dis[u] != MAX && temp < dis[v] )
77 {
78 dis[v] = temp;
79 flag = true;
80 }
81 }
82 if(!flag)//不松弛了,就可以提前跳出循环
83 break;
84 }
85
86 if(i == filed + 1)//如果无负权回路,最多松弛filed - 1次
87 return true;
88 return false;
89 /*
90 下面是判断是否有负权回路的通用方法
91 两种方法的效率相差无几
92 */
93
94 /*
95 for(i = 1 ; i <= total ; ++i)
96 if(dis[e[i].to] > dis[e[i].from] + e[i].tim)
97 return true;
98 return false;
99 */
100 }