题目背景
农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。
题目描述
约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。
你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000
输入输出格式
输入格式:
第一行: 农场的个数,N(3<=N<=100)。
第二行..结尾: 后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。
输出格式:
只有一个输出,其中包含连接到每个农场的光纤的最小长度。
题解:最小生成树裸题,并查集+kruskal
const
maxn=1000;
maxm=20000;
var
fa:array[0..maxn]of longint;
edge:array[0..maxm,1..3]of longint;
next,last:array[1..maxm]of longint;
n,sum,ans,i:longint;
procedure add(x,y,z:longint);
begin
inc(sum);
edge[sum,1]:=x;edge[sum,2]:=y;edge[sum,3]:=z;
next[sum]:=last[x];
last[x]:=sum;
end;
function find(x:longint):longint;
begin
if fa[x]=x then exit(x);
fa[x]:=find(fa[x]);
find:=fa[x];
end;
procedure union(x,y:longint);
var
u,v:longint;
begin
u:=find(x);v:=find(y);
if u<>v then fa[u]:=v;
end;
procedure qsort(l,r:longint);
var
i,j,key:longint;
begin
if l>r then exit;
i:=l;j:=r;
key:=edge[(i+j)div 2,3];
repeat
while edge[i,3]<key do inc(i);
while edge[j,3]>key do dec(j);
if i<=j then
begin
edge[0]:=edge[i];edge[i]:=edge[j];edge[j]:=edge[0];
inc(i);dec(j);
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
procedure init;
var
i,j,x:longint;
begin
readln(n);
for i:=1 to n do
begin
fa[i]:=i;
for j:=1 to n do
begin
read(x);
if i=j then continue;
add(i,j,x);
add(j,i,x);
end;
end;
qsort(1,sum);
end;
procedure kruskal;
var
i:longint;
begin
for i:=1 to sum do
begin
if find(edge[i,1])<>find(edge[i,2]) then
begin
union(edge[i,1],edge[i,2]);
inc(ans,edge[i,3]);
end;
end;
end;
begin
init;
kruskal;
writeln(ans);
end.