Kruskal算法(并查集+Qsort优化)
program busy_city;{Kruskal}
const maxn=300; maxm=maxn*maxn;
type
edge=record
v1,v2,cost:integer;
end;
arr=array[1..maxn]of integer;
edges=array[1..maxm]of edge;
var
p:edges;
n,m,ans:integer;
function find(father:arr; v:integer):integer;{并查集,寻找根结点的函数}
var t:integer;
begin
t:=v;
while(father[t]>=0) do t:=father[t];
find:=t;
end;
procedure init;{以边目录方式输入}
var i:integer;
begin
readln(n,m);
for i:=1 to m do with p[i] do readln(v1,v2,cost);
end;
procedure qsort(l,r:integer);{预处理:快速排序}
var
i,j,mid:integer;
t:edge;
begin
i:=l;
j:=r;
mid:=p[(l+r)shr 1].cost;
repeat
while(p[i].cost<mid)do inc(i);
while(p[j].cost>mid)do dec(j);
if i<=j then begin
t:=p[i];
p[i]:=p[j];
p[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
procedure kruskal;{Kruskal算法}
var
father:arr;
i,j,k,vf1,vf2:integer;
begin
qsort(1,m);
for i:=1 to n do father[i]:=-1;
i:=1;
j:=1;
while((i<=maxm) and (j<=n-1)) do begin
vf1:=find(father,p[i].v1);
vf2:=find(father,p[i].v2);
if vf1<>vf2 then begin
father[vf2]:=vf1;
inc(j);
writeln(p[i].v1,'---',p[i].v2);{输出MST中的边}
ans:=ans+p[i].cost;
end;
inc(i);
end;
end;
begin
init;
kruskal;
writeln('MST=',ans);{输出MST的最小代价}
readln
end.
program busy_city;{Kruskal}
const maxn=300; maxm=maxn*maxn;
type
edge=record
v1,v2,cost:integer;
end;
arr=array[1..maxn]of integer;
edges=array[1..maxm]of edge;
var
p:edges;
n,m,ans:integer;
function find(father:arr; v:integer):integer;{并查集,寻找根结点的函数}
var t:integer;
begin
t:=v;
while(father[t]>=0) do t:=father[t];
find:=t;
end;
procedure init;{以边目录方式输入}
var i:integer;
begin
readln(n,m);
for i:=1 to m do with p[i] do readln(v1,v2,cost);
end;
procedure qsort(l,r:integer);{预处理:快速排序}
var
i,j,mid:integer;
t:edge;
begin
i:=l;
j:=r;
mid:=p[(l+r)shr 1].cost;
repeat
while(p[i].cost<mid)do inc(i);
while(p[j].cost>mid)do dec(j);
if i<=j then begin
t:=p[i];
p[i]:=p[j];
p[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
procedure kruskal;{Kruskal算法}
var
father:arr;
i,j,k,vf1,vf2:integer;
begin
qsort(1,m);
for i:=1 to n do father[i]:=-1;
i:=1;
j:=1;
while((i<=maxm) and (j<=n-1)) do begin
vf1:=find(father,p[i].v1);
vf2:=find(father,p[i].v2);
if vf1<>vf2 then begin
father[vf2]:=vf1;
inc(j);
writeln(p[i].v1,'---',p[i].v2);{输出MST中的边}
ans:=ans+p[i].cost;
end;
inc(i);
end;
end;
begin
init;
kruskal;
writeln('MST=',ans);{输出MST的最小代价}
readln
end.