Submit: 4064 Solved: 2293
[Submit][Status][Discuss]
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不可能相同。
1<N<=500,1<=x,y<=N,0<v<30000,0<M<=5000
Output
如果景点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
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
IMPOSSIBLE
【样例输出2】
5/4
【样例输出3】
2
一开始想spfa,但是看了一下数据大小才5000条边。
直接枚举最小边和最大边,然后比较比值,最简分数用gcd解决
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 6 const int INF=0x7ffffff; 7 8 struct Edge 9 { 10 int u,v,w; 11 }E[10000]; 12 13 int n,m,s,t,tmp,minn=-1,maxn=-INF; 14 int F[1000]; 15 16 bool cmp(Edge A,Edge B) 17 { 18 return A.w<B.w; 19 } 20 21 int find(int a) 22 { 23 while(F[a]!=a) a=F[a]; 24 return a; 25 } 26 27 int gcd(int a,int b) 28 { 29 return b?gcd(b,a%b):a; 30 } 31 32 int main() 33 { 34 scanf("%d %d",&n,&m); 35 for(int i=0;i<m;i++) 36 { 37 int x,y,z; 38 scanf("%d %d %d",&x,&y,&z); 39 E[i]=(Edge){x,y,z}; 40 } 41 scanf("%d %d",&s,&t); 42 sort(E,E+m,cmp); 43 int i,j,S,T; 44 for(i=0;i<m;i++) 45 { 46 for(j=1;j<=n;j++) F[j]=j; 47 for(j=i;j<m;j++) 48 { 49 int u=find(E[j].u); 50 int v=find(E[j].v); 51 if(u!=v) F[u]=v; 52 S=find(s);T=find(t); 53 if(S==T) break; 54 } 55 if(S==T&&(double)maxn/(double)minn>(double)E[j].w/(double)E[i].w) 56 { 57 maxn=E[j].w; 58 minn=E[i].w; 59 } 60 } 61 if(minn==-1) printf("IMPOSSIBLE "); 62 else 63 { 64 tmp=gcd(maxn,minn); 65 if(minn/tmp==1) printf("%d",maxn/tmp); 66 else printf("%d/%d ",maxn/tmp,minn/tmp); 67 } 68 return 0; 69 }