最舒适的路线--河南省第六届大学生程序设计竞赛
题目描述
异形卵潜伏在某区域的一个神经网络中。其网络共有N个神经元(编号为1,2,3,…,N),这些神经元由M条通道连接着。两个神经元之间可能有多条通道。异形卵可以在这些通道上来回游动,但在神经网络中任一条通道的游动速度必须是一定的。当然异形卵不希望从一条通道游动到另一条通道速度变化太大,否则它会很不舒服。
现在异形卵聚居在神经元S点,想游动到神经元T点。它希望选择一条游动过程中通道最大速度与最小速度比尽可能小的路线,也就是所谓最舒适的路线。
输入
第一行: K 表示有多少组测试数据。
接下来对每组测试数据:
第1行: N M
第2~M+1行: Xi Yi Vi (i=1,…..,M)
表示神经元Xi 到神经元Yi之间通道的速度必须是Vi
最后一行: S T ( S ¹ T )
2≤K≤5 1<N≤500 0<M≤5000 1≤ Xi, Yi , S , T ≤N 0< Vi <30000,
Vi是整数。数据之间有一个空格。
输出
对于每组测试数据,输出一行:如果神经元S到神经元T没有路线,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
样例输入
2
3 2
1 2 2
2 3 4
1 3
3 3
1 2 10
1 2 5
2 3 8
1 3
样例输出
2
5/4
提示
来源
思路:枚举速度最大的那条边,一条条插入比它速度小的边,直到两地连通——这里可以使用并查集,逐个比较比值,取最小的就行了。
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #define INF 0xfffffff #define N 5500 using namespace std; int f[N]; struct node { int x,y,v; }; int cmp(node a,node b) { return a.v<b.v; } int gcd(int m,int n) { return n?gcd(n,m%n):m; } int Find(int x) { return x==f[x]?x:f[x]=Find(f[x]); } int main() { int n,p,q,T,m,i,j,minv,maxv; node a[N]; scanf("%d",&T); while(T--) { memset(a,0,sizeof(a)); scanf("%d %d",&n,&m); for(i=1;i<=m;i++) { scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].v); } scanf("%d%d",&p,&q); sort(a+1,a+m+1,cmp); double ans=INF; for(i=m;i>=1;i--)//从最大的边开始,将比它小的边加入 { for(j=1;j<=n;j++) f[j]=j; for(j=i;j>0;j--) { int x=Find(a[j].x); int y=Find(a[j].y); if(x!=y) { f[x]=y; } else continue ; if(Find(p)==Find(q))//起点和终点在都一个集合里 break; } if(j==0)//如果把边都加进去完了,说明起点和终点不连通 break; if(a[i].v*1.0/a[j].v<ans) { ans=a[i].v*1.0/a[j].v; maxv=a[i].v; minv=a[j].v; } } if(ans==INF) printf("IMPOSSIBLE\n"); else if(maxv%minv==0) printf("%d\n",maxv/minv); else printf("%d/%d\n",maxv/gcd(maxv,minv),minv/gcd(maxv,minv)); } return 0; }