转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1299075341
提示:
利用虫洞的时光旅行,很有趣的一道题。涉及到图论的知识,关键是构造图,用Bellman-Ford算法找出负权环
Bellman-Ford算法核心在于松弛,具体可以百度,这里就不重复前人的智慧了O(∩_∩)O哈哈~
需要注意的就是输入说明Input这部分,很多人读不懂这段题意:
正权(双向)边部分:
Line 1 of each farm: Three space-separated integers respectively: N, M, and W
Lines 2~M+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse.
Two fields might be connected by more than one path.
负权(单向)边部分:
Lines M+2~M+W+1 of each farm: Three space-separated numbers (S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.
1 //Memory Time
2 //308K 204MS
3
4 #include<iostream>
5 using namespace std;
6
7 int dis[1001]; //源点到各点权值
8 const int max_w=10001; //无穷远
9
10 class weight
11 {
12 public:
13 int s;
14 int e;
15 int t;
16 }edge[5200];
17
18 int N,M,W_h; //N (1≤N≤500)fields 顶点数
19 //M (1≤M≤2500)paths 正权双向边
20 //W_h (1≤W≤200) wormholes 虫洞(回溯),负权单向边
21 int all_e; //边集(边总数)
22
23 bool bellman(void)
24 {
25 bool flag;
26
27 /*relax*/
28
29 for(int i=0;i<N-1;i++)
30 {
31 flag=false;
32 for(int j=0;j<all_e;j++)
33 if(dis[edge[j].e] > dis[edge[j].s] + edge[j].t)
34 {
35 dis[edge[j].e] = dis[edge[j].s] + edge[j].t;
36 flag=true; //relax对路径有更新
37 }
38 if(!flag)
39 break; //只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax
40 }
41
42 /*Search Negative Circle*/
43
44 for(int k=0;k<all_e;k++)
45 if( dis[edge[k].e] > dis[edge[k].s] + edge[k].t)
46 return true;
47
48 return false;
49 }
50 int main(void)
51 {
52 int u,v,w;
53
54 int F;
55 cin>>F;
56 while(F--)
57 {
58 memset(dis,max_w,sizeof(dis)); //源点到各点的初始值为无穷,即默认不连通
59
60 cin>>N>>M>>W_h;
61
62 all_e=0; //初始化指针
63
64 /*read in Positive Paths*/
65
66 for(int i=1;i<=M;i++)
67 {
68 cin>>u>>v>>w;
69 edge[all_e].s=edge[all_e+1].e=u;
70 edge[all_e].e=edge[all_e+1].s=v;
71 edge[all_e++].t=w;
72 edge[all_e++].t=w; //由于paths的双向性,两个方向权值相等,注意指针的移动
73 }
74
75 /*read in Negative Wormholds*/
76
77 for(int j=1;j<=W_h;j++)
78 {
79 cin>>u>>v>>w;
80 edge[all_e].s=u;
81 edge[all_e].e=v;
82 edge[all_e++].t=-w; //注意权值为负
83 }
84
85 /*Bellman-Ford Algorithm*/
86
87 if(bellman())
88 cout<<"YES"<<endl;
89 else
90 cout<<"NO"<<endl;
91 }
92 return 0;
93 }