【模板】最小生成树
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz
输入输出格式
输入格式:
第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式:
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
输入输出样例
4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 4 3
7
说明
时空限制:1000ms,128M
数据规模:
对于20%的数据:N<=5,M<=20
对于40%的数据:N<=50,M<=2500
对于70%的数据:N<=500,M<=10000
对于100%的数据:N<=5000,M<=200000
样例解释:
所以最小生成树的总边权为2+2+3=7
var
a:array[0..5000,0..5000]of longint;
low:array[0..5000]of longint;
f:array[0..5000]of boolean;
x,y,z,i,j,k,n,m,min,num,ans:longint;
begin
fillchar(f,sizeof(f),true);
readln(n,m);
for i:=1 to m do
begin
read(x,y,z);
if a[x,y]=0 then a[x,y]:=maxlongint;
if z<a[x,y] then a[x,y]:=z;
a[y,x]:=a[x,y];
end;
for i:=1 to n do
if a[1,i]<>0 then low[i]:=a[1,i]
else low[i]:=maxlongint;
f[1]:=false;
for i:=1 to n-1 do
begin
min:=maxlongint;
for j:=1 to n do
begin
if (f[j])and(low[j]<min) then
begin
min:=low[j];
num:=j;
end;
end;
ans:=ans+min;
f[num]:=false;
for j:=1 to n do
if (a[num,j]<low[j])and(a[num,j]<>0) then
low[j]:=a[num,j];
end;
write(ans);
end.