题意:
Z小镇附近共有N个景点,这些景点被M条道路连接着,所有道路都是双向的,对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。最大速度和最小速度的比尽可能小的路线。(
n<500 m<5000 v<30000)
思路
用最短路得话好像不是很好搞,反正我是没有想出怎么最短路,然后正好在学并查集。就用并查集搞了一波。
给他的边按速度排序,然后一个个枚举,找到哪一个就可以联通了,因为是排序过得,找到一个后就可以换一个起点再查,如果无法联通就可以退出了
时间复杂度
m个枚举起点,每个起点m次以下,并查集加上路径压缩也就1。所以为O(m*m);
const
maxn=300000;
var
f,x,y,v:array [0..maxn] of longint;
i,j,k,n,m,x1,y1,p,q,max,min:longint;
function gcd(x,y:longint):longint;
var
i,p:longint;
begin
p:=x;
if p>y then p:=y;
for i:=p downto 1 do
if (x mod i=0) and (y mod i=0) then exit(i);
end;
procedure qsort(l,r:longint);
var
i,j,mid:longint;
begin
i:=l; j:=r;
mid:=v[(l+r) div 2];
while i<j do
begin
while v[i]<mid do inc(i);
while v[j]>mid do dec(j);
if i<=j then
begin
v[0]:=v[i];
v[i]:=v[j];
v[j]:=v[0];
x[0]:=x[i];
x[i]:=x[j];
x[j]:=x[0];
y[0]:=y[i];
y[i]:=y[j];
y[j]:=y[0];
inc(i); dec(j);
end;
end;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
function father(x:longint):longint;
var
i,j:longint;
begin
if x<>f[x] then father:=father(f[x])
else father:=x;
f[x]:=father;
end;
begin
max:=maxlongint;
min:=1;
readln(n,m);
for i:=1 to m do
readln(x[i],y[i],v[i]);
readln(x1,y1);
qsort(1,m);
for i:=1 to n do
f[i]:=i;
for i:=1 to m do
begin
j:=i-1;
p:=v[i];
while (j<=m) and (father(x1)<>father(y1)) do
begin
inc(j);
f[father(x[j])]:=f[father(y[j])];
q:=v[j];
end;
if father(x1)<>father(y1) then break;
if q/p<max/min then
begin
max:=q;
min:=p;
end;
for j:=1 to n do
f[j]:=j;
end;
if max=maxlongint then
begin
writeln('IMPOSSIBLE');
halt;
end;
q:=gcd(max,min);
max:=max div q;
min:=min div q;
if min=1 then writeln(max)
else writeln(max,'/',min) ;
end.