枚举+并查集 之 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 }

 

 

 

 
posted @ 2015-12-11 20:07  JmingS  阅读(160)  评论(0编辑  收藏  举报