题目地址:http://codevs.cn/problem/1001/
分析:
简单的并查集
把边权按从小到大的顺序排好序枚举每一条边,把这条边的边权作为ans_max,接下来从这条边开始按顺序(从大到小)枚举每一条比它小的边,并且把这条边的两端点划分到一个联通块中,并且判断起点和终点是否在同一个联通块中,如果在同一个联通块中,那么当前枚举到的边的权值就是ans_min,然后更新当前最优解即可。
原理:枚举、贪心,因为我们要求ans_max与ans_min的最小比值,ans_max与ans_min越接近肯定是越好的。所以我们枚举ans_max,这样就可以把ans_max当成常数,那么ans_min的值一定是越大越好(当然,它不可能大过ans_max),所以我们从当前枚举到的边开始,每次加一条略小的边进入,当S与T第一次联通时,ans_min的值是最大的,那么就能保证他们的比值是当前ans_max下最小的。
type
node=record
f,t:longint;
end;
node1=record
a,b,v:longint;
end;
node2=record
v1,v2:longint;
v:real;
end;
var
max:real;
n,m,i,a,b,v,j,l,r,maxv1,maxv2,xb:longint;
f:array[0..501] of node;
g:array[0..5001] of node1;
procedure print(x,y:longint);
var
a,b,r,t:longint;
begin
if x<y then begin t:=x;x:=y;y:=t end;
a:=x;b:=y;
r:=a mod b;
while r<>0 do
begin
a:=b;
b:=r;
r:=a mod b;
end;
if y div b=1 then writeln(x div b)
else writeln(x div b,'/',y div b);
halt;
end;
procedure sort(l,r: longint);
var
i,j,x: longint;
y: node1;
begin
i:=l;
j:=r;
x:=g[(l+r) div 2].v;
repeat
while g[i].v>x do
inc(i);
while x>g[j].v do
dec(j);
if not(i>j) then
begin
y:=g[i];
g[i]:=g[j];
g[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
function find(x:longint):longint;
begin
if f[x].f=x then exit(x)
else begin
f[x].f:=find(f[x].f);
exit(f[x].f);
end;
end;
procedure union(x,y:longint);
var
a,b:longint;
begin
a:=find(x);
b:=find(y);
if a=b then exit;
if f[a].t<f[b].t
then begin f[a].f:=b;inc(f[b].t,f[a].t); end
else begin f[b].f:=a;inc(f[a].t,f[b].t); end;
end;
function check(x,y:longint):boolean;
begin
if find(x)=find(y)then exit(true)
else exit(false);
end;
begin
readln(n,m);
for i:=1 to n do begin f[i].f:=i;f[i].t:=1; end;
for i:=1 to m do
begin
read(a,b,v);
union(a,b);
g[i].a:=a;g[i].b:=b;g[i].v:=v;
end;
readln(l,r);
if not check(l,r) then begin writeln('IMPOSSIBLE');halt end;
sort(1,m);
max:=maxlongint;
for i:=1 to m do
begin
for j:=1 to n do begin f[j].f:=j;f[j].t:=1;end;
for j:=i to m do
begin
union(g[j].a,g[j].b);
if check(l,r) then break;
end;
if not check(l,r) then continue;
if (g[i].v/g[j].v<max) and (i<>j)
then begin
max:=g[i].v/g[j].v;
maxv1:=g[i].v;maxv2:=g[j].v;
end;
end;
if maxv2=0 then print(1,1)
else print(maxv1,maxv2);
end.