Description
给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。
Input
第一行包含两个正整数,N和M。 下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
Output
如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
枚举每条边作为最小边并求最小生成树得到最大边
#include<cstdio> #include<algorithm> struct edge{ int x,y,v; }; bool operator<(edge a,edge b){ return a.v<b.v; } edge es[5005]; int f[505]; int n,m,x,y,v,S,T; int gcd(int a,int b){ if(!b)return a; return gcd(b,a%b); } inline int get(int x){ int a=x,c; while(a!=f[a])a=f[a]; while(a!=(c=f[x]))f[x]=a,x=c; return a; } int main(){ int mn=-1,mx; double ans=1e10; scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ scanf("%d%d%d",&es[i].x,&es[i].y,&es[i].v); } scanf("%d%d",&S,&T); std::sort(es,es+m); for(int i=0;i<m;i++){ for(int j=0;j<=n;j++)f[j]=j; for(int j=i;j<m;j++){ x=get(es[j].x); y=get(es[j].y); if(x!=y)f[x]=y; if(get(S)==get(T)){ double s=double(es[j].v)/es[i].v; if(s<ans){ ans=s; mn=es[i].v;mx=es[j].v; } break; } } } if(~mn){ int g=gcd(mn,mx); mn/=g;mx/=g; if(mn>1)printf("%d/%d",mx,mn); else printf("%d",mx); }else puts("IMPOSSIBLE"); return 0; }