枚举+并查集 之 CODE[VS] 1001 舒适的路线 2006年
/*
枚举所有情况,通过并查集判断在当前情况下,是否包含起始和终止点,
若包含,则需判断是否在当前情况下,最大速度和最小速度的比更小,
若是,则更新最大速度和最小速度。
最后枚举过所有情况后,即获得答案。
*/
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstddef> 5 #include <iterator> 6 #include <algorithm> 7 #include <string> 8 #include <locale> 9 #include <cmath> 10 #include <vector> 11 #include <cstring> 12 #include <map> 13 #include <utility> 14 #include <queue> 15 #include <stack> 16 #include <set> 17 #include <functional> 18 using namespace std; 19 typedef pair<int, int> P; 20 const int INF = 0x3f3f3f3f; 21 const int modPrime = 3046721; 22 const double eps = 1e-9; 23 const int MaxN = 505; 24 const int MaxM = 5005; 25 26 27 int N, M, s, t; 28 string exampleNum; 29 30 struct Node 31 { 32 int x, y, v; 33 }; 34 35 Node nodeVec[MaxM]; 36 37 bool Cmp(const Node n1, const Node n2) 38 { 39 return n1.v < n2.v; 40 } 41 42 43 int gcd(int a, int b) 44 { 45 if (b == 0) return a; 46 else gcd(b, a%b); 47 } 48 49 50 /////////////////////////////////// 51 //并查集(Union-Find Sets) 52 int ifather[MaxN]; 53 int irank[MaxN]; 54 55 void ufsinit(int n) 56 { 57 for (int i = 0; i <= n; ++i) 58 { 59 ifather[i] = i; 60 irank[i] = 0; 61 } 62 } 63 64 int ufsFind(int x) 65 { 66 if (ifather[x] == x) 67 { 68 return x; 69 } 70 else 71 { 72 return ifather[x] = ufsFind(ifather[x]); 73 } 74 } 75 76 void ufsUnite(int x, int y) 77 { 78 x = ufsFind(x); 79 y = ufsFind(y); 80 81 if (x == y) 82 { 83 return; 84 } 85 86 if (irank[x] < irank[y]) 87 { 88 ifather[x] = y; 89 } 90 else 91 { 92 ifather[y] = x; 93 if (irank[x] == irank[y]) 94 { 95 ++irank[x]; 96 } 97 } 98 } 99 100 /////////////////////////////////// 101 102 void Solve() 103 { 104 int ansMax = INF; 105 int ansMin = 1; 106 bool havePath = false; 107 for (int i = 0; i < M; ++i) 108 { 109 ufsinit(N); 110 for (int j = i; j >= 0; --j) 111 { 112 ufsUnite(nodeVec[j].x, nodeVec[j].y); 113 if (ufsFind(s) == ufsFind(t)) 114 { 115 if ((ansMax*1.0 / ansMin) - (nodeVec[i].v*1.0 / nodeVec[j].v) > eps) 116 { 117 ansMax = nodeVec[i].v; 118 ansMin = nodeVec[j].v; 119 if (!havePath) 120 { 121 havePath = true; 122 } 123 } 124 break; 125 } 126 } 127 } 128 if (!havePath) 129 { 130 printf("IMPOSSIBLE\n"); 131 } 132 else 133 { 134 int iGcd = gcd(ansMax, ansMin); 135 ansMax /= iGcd; 136 ansMin /= iGcd; 137 if (ansMin == 1) 138 { 139 printf("%d\n", ansMax); 140 } 141 else 142 { 143 printf("%d/%d\n", ansMax, ansMin); 144 } 145 } 146 } 147 148 int main() 149 { 150 #ifdef HOME 151 freopen("in", "r", stdin); 152 //freopen("out", "w", stdout); 153 #endif 154 155 while (~scanf("%d %d", &N, &M)) 156 { 157 Node nd; 158 for (int i = 0; i < M; ++i) 159 { 160 scanf("%d %d %d", &nd.x, &nd.y, &nd.v); 161 nodeVec[i] = nd; 162 } 163 sort(nodeVec, nodeVec + M, Cmp); 164 scanf("%d %d", &s, &t); 165 Solve(); 166 } 167 168 #ifdef HOME 169 cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; 170 _CrtDumpMemoryLeaks(); 171 #endif 172 return 0; 173 }