您的位置:首页 > 其它

bzoj 1050: [HAOI2006]旅行comf 并查集

2016-05-20 17:39 555 查看
题意:给出一个无向图,找出从起点到终点的一条路径使得最大边比最下边的值最小。

分析:先把边按权值排序。然后枚举每条边,使该边为权值最小的边,然后不断往里面加边,用并查集判断起点和终点是否连通。

代码:

var
s,t,n,m:longint;
a:array[0..5000,1..3] of longint;
f:array[1..500] of longint;

procedure init;
var
i:longint;
begin
readln(n,m);
for i:=1 to m do
readln(a[i,1],a[i,2],a[i,3]);
readln(s,t);
end;

procedure qsort(l,r:longint);
var
i,j,k:longint;
begin
if l>=r then exit;
i:=l;
j:=r;
k:=a[(i+j) div 2,3];
repeat
while a[i,3]<k do inc(i);
while a[j,3]>k do dec(j);
if i<=j then
begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
inc(i);dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;

function find(x:longint):longint;
begin
if f[x]=x then exit(x);
find:=find(f[x]);
f[x]:=find;
end;

function gcd(x,y:longint):longint;
begin
if x mod y=0 then exit(y);
gcd:=gcd(y,x mod y);
end;

procedure main;
var
ans:real;
x,y,z,i,j:longint;
begin
qsort(1,m);
ans:=maxlongint;
for i:=1 to m do
begin
for j:=1 to n do
f[j]:=j;
j:=i;
while j<=m do
begin
if a[j,3]/a[i,3]>=ans then break;
if find(a[j,1])<>find(a[j,2]) then
begin
f[find(a[j,1])]:=find(a[j,2]);
if find(s)=find(t) then
begin
if 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;
break;
end;
end;
inc(j);
end;
end;
if ans=maxlongint
then writeln('IMPOSSIBLE')
else begin
z:=gcd(x,y);
x:=x div z;
y:=y div z;
if y=1
then writeln(x)
else writeln(x,'/',y);
end;
end;

begin
init;
main;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: