Description
给出N个点的坐标,对它们建立一个最小生成树,代价就是连接它们的路径的长度,现要求总长度最小。N的值在100以内,坐标值在[-10000,10000].结果保留二位小数
Input
5 —————5个点
0 0 —————5个点点的坐标
0 1
1 1
1 0
0.5 0.5
Output
2.83
题解:
用了prim和克鲁斯卡尔两种方法,具体参照:
http://blog.csdn.net/qq_34593871/article/details/53322492
代码:
prim:
var
a:array[1..200,1..200] of real;
d:array[1..200,1..2] of real;
b:array[1..1000] of longint;
n,i,j,k,x:longint;
min,ans:real;
procedure init;
begin
readln(n);
for i:=1 to n do
readln(d[i,1],d[i,2]);
for i:=1 to n do
for j:=1 to n do
a[i,j]:=sqrt(sqr(d[i,1]-d[j,1])+sqr(d[i,2]-d[j,2]));
end;
begin
init;
b[1]:=1;
for i:=1 to n-1 do
begin
min:=maxlongint;
for j:=1 to n do
if b[j]=1 then
for k:=1 to n do
if (b[k]=0)and(a[j,k]<>0)and(a[j,k]<min) then
begin
min:=a[j,k];
x:=k;
end;
if min<>maxlongint then
begin
ans:=ans+min;
b[x]:=1;
end;
end;
writeln(ans:0:2);
end.
克鲁斯卡尔:
var
a:array[1..200,1..200] of real;
d:array[1..200,1..2] of real;
b:array[1..1000] of longint;
n,i,j,k,x,y,c:longint;
min,ans:real;
procedure init;
begin
readln(n);
for i:=1 to n do
readln(d[i,1],d[i,2]);
for i:=1 to n do
for j:=1 to n do
a[i,j]:=sqrt(sqr(d[i,1]-d[j,1])+sqr(d[i,2]-d[j,2]));
end;
begin
init;
for i:=1 to n do b[i]:=i;
for i:=1 to n-1 do
begin
min:=maxlongint;
for j:=1 to n do
for k:=1 to n do
if (b[j]<>b[k])and(a[j,k]<>0)and(a[j,k]<min) then
begin
min:=a[j,k];
x:=j;
y:=k;
end;
ans:=ans+min;
c:=b[y];
for j:=1 to n do if b[j]=c then b[j]:=b[x];
end;
writeln(ans:0:2);
end.