题意:
找一课最小生成树
思路:
基本思想:每次选不属于同一连通分量(保证无圈)且边权值最小的2个顶点,将边加入MST,并将所在的2个连通分量合并,直到只剩一个连通分量
算法实现:
将边按非降序排列(Quicksort,O(E㏒E))
While 合并次数少于|V|-1
取一条边(u,v)(因为已经排序,所以必为最小)
If u,v不属于同一连通分量 then
合并u,v所在的连通分量
输出边(u,v)
合并次数增1;tot=tot+W(u,v)
算法结束:tot为MST的总权值
直接复制了一波课件,因为这题太简单、
type
arr=record
x,y,w:longint;
end;
const
maxn=1000;
var
a:array [0..maxn*maxn] of arr;
f:array [0..maxn*maxn] of longint;
i,j,n,m,p,ans:longint;
procedure qsort(l,r:longint);
var
i,j,mid:longint;
begin
i:=l; j:=r;
mid:=a[(l+r) div 2].w;
while i<j do
begin
while a[i].w<mid do inc(i);
while a[j].w>mid 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;
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
readln(n);
for i:=1 to n do
begin
for j:=1 to n do
if i<j then
begin
inc(p);
read(a[p].w);
a[p].x:=i;
a[p].y:=j;
end;
readln;
end;
qsort(1,p);
for i:=1 to p do
f[i]:=i;
for i:=1 to p do
if f[father(a[i].x)]<>f[father(a[i].y)] then
begin
f[father(a[i].x)]:=f[father(a[i].y)];
ans:=ans+a[i].w;
end;
writeln(ans);
end.