Wiki OI 1001 舒适的路线

题目链接:http://wikioi.com/problem/1001/

算法与思路:并查集,首先枚举速度最大的那条边,然后把速度大于这条边的边都删掉,
接下来的任务就是在残图中寻找一条路,路上的最小的那条边要尽量大。
这个地方用并查集实现,对于剩下的边由大到小排序,
然后逐个往集合里面加,直到某次加入操作后起点和终点被加到了同一个集合,
这时停止操作,最后加的那条边就是一条所求的最小边最大的。算法复杂度O(m^2)。

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#define INF 0xffffff
using namespace std;
int set[505];
int n, m, s, t, k;
int Max, Min; 
struct node
{
   int x;
   int y;
   int v;
}edge[5005];
bool cmp(node a, node b)
{
	return a.v < b.v;
}
int find(int x)
{
	return x == set[x] ? x : set[x] = find(set[x]); 
}
int gcd(int a, int b)
{
	return b ? gcd(b, a % b) : a;
}
int main()
{
   double ans = INF;
   scanf("%d %d",&n, &m);
   for(int i = 1; i <= m; ++i)
   		scanf("%d %d %d", &edge[i].x, &edge[i].y, &edge[i].v);
   scanf("%d %d", &s, &t);
   sort(edge + 1, edge + m + 1, cmp);
   for(int i = 1; i <= m; ++i)
   {
       for(int j = 1; j <= n; ++j)
	       set[j] = j;
       for(k = i; k <= m; ++k)
       {
           if(find(edge[k].x) != find(edge[k].y))
		       set[set[edge[k].x]] = set[edge[k].y];
           if(find(s) == find(t))
		   {
		       if(edge[k].v / 1.0 / edge[i].v < ans)
			   {
			       Max = edge[k].v;
				   Min = edge[i].v;
			       ans = edge[k].v / 1.0 / edge[i].v;
               }
               break;
           }
       }
   }
   if(ans == INF)
       printf("IMPOSSIBLE\n");
   else
   {
       int temp = gcd(Max, Min);
       Max /= temp; 
	   Min /= temp;
       printf("%d",Max);
       if(Min != 1)
	       printf("/%d",Min);
	    printf("\n");
   }
   return 0;
}


你可能感兴趣的:(Wiki OI 1001 舒适的路线)