题目描述 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范围内
解题思路
好吧,我承认我看了题解,这个题是一个并查集的变形,把价值由小到大排序,之后,枚举每一条边,然后把它当做最大值,再从大到小枚举比该边小的边,同时判断起点和终点是否联通,联通就确定最小值,更新ans。
但是刚开始做的时候我忘记更新ans了,汗汗汗!
1 program saft; 2 type aa=record 3 l,r,v:Longint 4 end; 5 var a:array[0..5000] of aa; 6 n,m,w,i,j,max,min,maxx,minn,st,ed:longint; 7 ans:real; 8 f:array[1..500] of longint; 9 procedure sort(l,r: longint); 10 var 11 i,j,x,y: longint; 12 begin 13 i:=l; 14 j:=r; 15 x:=a[(l+r) div 2].v; 16 repeat 17 while a[i].v<x do 18 inc(i); 19 while x<a[j].v do 20 dec(j); 21 if not(i>j) then 22 begin 23 a[0]:=a[i]; 24 a[i]:=a[j]; 25 a[j]:=a[0]; 26 inc(i); 27 j:=j-1; 28 end; 29 until i>j; 30 if l<j then 31 sort(l,j); 32 if i<r then 33 sort(i,r); 34 end; 35 36 function root(x:longint):Longint; 37 begin 38 if f[x]=x then exit(x); 39 f[x]:=root(f[x]); 40 exit(f[x]); 41 end; 42 43 function gcd(x,y:Longint):Longint; 44 begin 45 if x mod y=0 then exit(y); 46 exit(gcd(y,x mod y)); 47 end; 48 49 begin 50 read(n,m); 51 52 for i:=1 to m do 53 read(a[i].l,a[i].r,a[i].v); 54 read(st,ed); 55 sort(1,m); 56 //min:=1; 57 max:=maxLongint; 58 ans:=maxlongint div 2; 59 for i:=2 to m do 60 begin 61 max:=a[i].v; 62 63 for j:=1 to n do f[j]:=j; 64 f[root(a[i].l)]:=root(a[i].r); 65 for j:=i downto 1 do 66 begin 67 if (root(st)<>root(ed)) and (root(a[j].l)<>root(a[j].r)) then 68 f[root(a[j].l)]:=root(a[j].r); 69 if root(st)=root(ed) then min:=a[j].v; 70 if (root(st)=root(ed))and (max/ min<ans) then 71 begin 72 minn:=min; 73 maxx:=max; 74 ans:=max/min; 75 end; 76 if root(st)=root(ed) then break; 77 end; 78 end; 79 if min=0 then 80 begin 81 writeln('IMPOSSIBLE'); 82 halt; 83 end; 84 w:=gcd(maxx,minn); 85 if minn div w=1 then writeln(maxx div w) else 86 writeln(maxx div w,'/',minn div w); 87 end.