Description
Z 小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。Z 小镇附近共有N 个景点(编号为1,2,3,…,N),这些景点被M 条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地的旅游资源,Z 小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。
速度变化太快使得游客们很不舒服,因此从一个景点前往另一个景点的时候,大家都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。
Input
第一行包含两个正整数,N 和M。
接下来的M 行每行包含三个正整数:x,y 和v。表示景点x 到景点y 之间有一条双向公路,车辆必须以速度v 在该公路上行驶。
最后一行包含两个正整数s,t,表示想知道从景点s 到景点t 最大最小速度比最小的路径。s 和t 不可能相同。
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
Sample Output
【样例输出1】
IMPOSSIBLE
【样例输出2】
5/4
【样例输出3】
2
DataConstraint
Hint
【数据范围】
对于100%的数据,1 < N≤500,1≤x,y≤N,0
分析:先把权值排序。然后把任意一条边当作最小权边。然后插入比它大的边,直到景点s和景点t连同,这时最后插入的边一定是权值最大的。把每条边的最大和最小的比求出,取最小值,用辗转相除约分即可。如果全部边都插入了,都没连同,就无解。插入并查集可以快速求解。
程序:
<span style="font-size:18px;">var
p:Array [1..500] of longint;
a:array [1..10000,1..3] of longint;
n,i,j,m,st,ed,x,y,s,t:longint;
ans:real;
function find(x:longint):longint;
var y,root,w:longint;
begin
y:=x;
while p[y]>0 do
y:=p[y];
root:=y;
y:=x;
while p[y]>0 do
begin
w:=p[y];
p[y]:=root;
y:=w;
end;
find:=root;
end;
procedure union(x,y:longint);
var u,v:longint;
begin
u:=find(x);
v:=find(y);
if u<>v then p[v]:=u;
end;
procedure qsort(l,r:longint);
var
i,j,key,temp:longint;
begin
if l>=r then exit;
i:=l;j:=r;
key:=a[l+random(r-l+1),3];
repeat
while (a[i,3]>key) do inc(i);
while (a[j,3]<key) do dec(j);
if i<=j then
begin
temp:=a[i,1];a[i,1]:=a[j,1];a[j,1]:=temp;
temp:=a[i,2];a[i,2]:=a[j,2];a[j,2]:=temp;
temp:=a[i,3];a[i,3]:=a[j,3];a[j,3]:=temp;
inc(i);dec(j);
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
procedure pig(var x,y:longint);
var s,t,r:longint;
begin
s:=x; t:=y;
while s mod t<>0 do
begin
r:=s mod t;
s:=t;
t:=r;
end;
x:=x div t;
y:=y div t;
end;
begin
readln(n,m);
for i:=1 to m do
begin
for j:=1 to 3 do
read(a[i,j]);
readln;
end;
readln(st,ed);
qsort(1,m);
ans:=6666666666;
for i:=1 to m do
begin
fillchar(p,sizeof(p),0);
j:=i+1;
while (find(st)<>find(ed)) and (j>1) do
begin
dec(j);
union(a[j,1],a[j,2]);
end;
s:=find(st);
t:=find(ed);
if (s<>t) and (i=m) then begin writeln('IMPOSSIBLE'); exit; end;
if (s=t) and (a[j,3]/a[i,3]<ans) then
begin ans:=a[j,3]/a[i,3]; x:=a[j,3]; y:=a[i,3]; end;
end;
pig(x,y);
if y>1 then writeln(x,'/',y)
else writeln(x);
end.
</span>