题意:
农夫 FJ 有 N 块田地【编号 1...n】 (1<=N<=500)
田地间有 M 条路径 【双向】(1<= M <= 2500)
同时有 W 个孔洞,可以回到以前的一个时间点【单向】(1<= W <=200)
问:FJ 是否能在田地中遇到以前的自己
解题思路:跟我昨天做的一个题思路差不多,这道题判断有无负权环就行了,昨天做的链接https://www.cnblogs.com/ducklu/p/9231563.html
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #define INF 1000000 5 #define MAXVERTEXNUM 505 6 #define MAXEDGENUM 10000 7 using namespace std; 8 9 int Nv, Ne1, Ne2, num; 10 int dist[MAXVERTEXNUM]; 11 struct E 12 { 13 int a, b, Weight; 14 }Edge[MAXEDGENUM]; 15 16 bool BellManFord() 17 { 18 for (int i = 1; i < Nv; ++i) 19 { 20 bool flag = false; 21 for (int j = 0; j < num; ++j) 22 { 23 if (dist[Edge[j].b] > dist[Edge[j].a] + Edge[j].Weight) 24 { 25 dist[Edge[j].b] = dist[Edge[j].a] + Edge[j].Weight; 26 flag = true; 27 } 28 } 29 if (!flag) 30 break; 31 } 32 33 for (int i = 0; i < num; ++i) 34 if (dist[Edge[i].b] > dist[Edge[i].a] + Edge[i].Weight) 35 return true; 36 37 return false; 38 } 39 40 int main() 41 { 42 ios::sync_with_stdio(false); 43 44 int cas; 45 cin >> cas; 46 while (cas--) 47 { 48 num = 0; 49 cin >> Nv >> Ne1 >> Ne2; 50 for (int i = 0; i < Ne1; ++i) 51 { 52 int V1, V2, W; 53 cin >> V1 >> V2 >> W; 54 Edge[num].a = V1, Edge[num].b = V2; 55 Edge[num++].Weight = W; 56 Edge[num].a = V2, Edge[num].b = V1; 57 Edge[num++].Weight = W; 58 } 59 60 for (int i = 0; i < Ne2; ++i) 61 { 62 int V1, V2, W; 63 cin >> V1 >> V2 >> W; 64 Edge[num].a = V1, Edge[num].b = V2; 65 Edge[num++].Weight = -W; 66 } 67 68 //init 69 for (int i = 1; i <= Nv; ++i) 70 dist[i] = INF; 71 dist[1] = 0; 72 73 if (BellManFord()) 74 cout << "YES" << endl; 75 else 76 cout << "NO" << endl; 77 } 78 79 return 0; 80 }