题目描述 Description
Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。
Z小镇附近共有
N(1<N≤500)个景点(编号为1,2,3,…,N),这些景点被M(0<M≤5000)条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。频繁的改变速度使得游客们很不舒服,因此大家从一个景点前往另一个景点的时候,都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。
输入描述 Input Description
第一行包含两个正整数,N和M。
接下来的M行每行包含三个正整数:x,y和v(1≤x,y≤N,0 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
输出描述 Output Description
如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
样例输入 Sample Input
样例1
4 2
1 2 1
3 4 2
1 4
样例2
3 3
1 2 10
1 2 5
2 3 8
1 3
样例3
3 2
1 2 2
2 3 4
1 3
样例输出 Sample Output
样例1
IMPOSSIBLE
样例2
5/4
样例3
2
数据范围及提示 Data Size & Hint
N(1<N≤500)
M(0<M≤5000)
Vi在int范围内
【题目分析】
首先我们可以发现,输出impossible的情况,如果两个点的father不是同一个那么无法连通
如果能连通的话,找到所有边中最大的和最小的,然后一边建边一边判断,一直建到两个节点能联通时,此时的maxn和minn就是最大值和最小值,然后比较与ans的大小,如果比ans小就算是比较舒适的路线,改变值
最后一个gcd 因为要输出既约分数
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,m; struct node { int st,en,dis; }a[5005]; int father[505],start,end; int getfa(int x) { if(father[x]==x) return x; else return father[x]=getfa(father[x]); } void unite(int x,int y) { int xx=getfa(x); int yy=getfa(y); if(xx!=yy) father[yy]=xx; } int GCD(int x,int y) { if(x%y==0) return y; else return GCD(y,x%y); } bool cmp(node x,node y) { return x.dis<y.dis; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].st,&a[i].en,&a[i].dis); for(int i=1;i<=n;i++) father[i]=i; for(int i=1;i<=m;i++) unite(a[i].st,a[i].en); scanf("%d%d",&start,&end); if(getfa(start)!=getfa(end)) { printf("IMPOSSIBLE"); return 0; } sort(a+1,a+m+1,cmp); double ans=1000010; double maxn,minn; int max1,min1; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) father[j]=j; maxn=a[i].dis; for(int j=i;j>=1;j--) { minn=a[j].dis; unite(a[j].st,a[j].en); if(getfa(start)==getfa(end)) { if((maxn/minn)<ans) { max1=maxn; min1=minn; ans=maxn/minn; break; } break; } } } if(max1%min1==0) { cout<<max1/min1; return 0; } else { cout<<max1/GCD(max1,min1)<<"/"<<min1/GCD(max1,min1); return 0; } }