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
题目中要求的最小比值涉及两个值,因此枚举其中一个,再贪心求另一个。比如先枚举最小的,然后将比它大的边按从小到大的顺序加入并查集,直到s和t连通,最后加入的边就是最好的最大边。
1 program rrr(input,output); 2 const 3 inf=123456789; 4 eps=1e-8; 5 var 6 u,v,w:array[0..5050]of longint; 7 father:array[0..505]of longint; 8 n,m,s,t,i,j,c,d,p,q:longint; 9 min:double; 10 procedure sort(q,h:longint); 11 var 12 i,j,x,t:longint; 13 begin 14 i:=q;j:=h;x:=w[(i+j)>>1]; 15 repeat 16 while w[i]<x do inc(i); 17 while x<w[j] do dec(j); 18 if i<=j then 19 begin 20 t:=u[i];u[i]:=u[j];u[j]:=t; 21 t:=v[i];v[i]:=v[j];v[j]:=t; 22 t:=w[i];w[i]:=w[j];w[j]:=t; 23 inc(i);dec(j); 24 end; 25 until i>j; 26 if j>q then sort(q,j); 27 if i<h then sort(i,h); 28 end; 29 function find(k:longint):longint; 30 begin 31 if father[k]=k then exit(k); 32 father[k]:=find(father[k]); 33 exit(father[k]); 34 end; 35 function gcd(a,b:longint):longint; 36 var 37 r:longint; 38 begin 39 r:=a mod b; 40 while r<>0 do begin a:=b;b:=r;r:=a mod b; end; 41 exit(b); 42 end; 43 begin 44 assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output); 45 readln(n,m); 46 for i:=1 to m do readln(u[i],v[i],w[i]); 47 readln(s,t); 48 sort(1,m); 49 min:=inf; 50 for i:=1 to m do 51 begin 52 for j:=1 to n do father[j]:=j; 53 for j:=i to m do 54 begin 55 c:=find(u[j]);d:=find(v[j]); 56 if c<>d then father[c]:=d; 57 c:=find(s);d:=find(t); 58 if c=d then break; 59 end; 60 if c=d then if w[j]/w[i]<min then begin min:=w[j]/w[i];p:=w[i];q:=w[j]; end; 61 end; 62 if abs(min-inf)<eps then write('IMPOSSIBLE') 63 else begin c:=gcd(p,q);p:=p div c;q:=q div c;if p=1 then write(q) else write(q,'/',p); end; 64 close(input);close(output); 65 end.