您的位置:首页 > 理论基础 > 计算机网络

【USACO题库】3.1.1 Agri-Net最短网络

2017-07-12 14:18 288 查看

【USACO题库】3.1.1 Agri-Net最短网络

题目:农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000输入:
第一行:农场的个数,N(3<=N<=100)。
第二行..结尾:后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。
输出:只有一个输出,其中包含连接到每个农场的光纤的最小长度。数据范围:见题目这几天在做图论专题,找到了这道USACO题拿来练习一下没想到以前的神题竟然如此之水!就是一道最小生成树的题目,乍一看数据范围也没有什么特殊果断prim,一次过标程(prim):
var     a:array[0..1000000,1..3]of longint;
bz:array[1..1000]of boolean;
st,en:array[0..1000]of longint;
last:array[0..1000]of longint;
map:array[1..1000,1..1000]of longint;
dian,bian:array[0..1000]of longint;
n,m,min,i,j,k,l,s,x,y,tot,ans,len,v:longint;
begin
readln(n);
for i:=1 to n do
for j:=1 to n do
begin
read(map[i,j]);
if map[i,j]<>0 then
begin
inc(len);
a[len,1]:=i;
a[len,2]:=j;
a[len,3]:=map[i,j];
end;
end;
x:=a[1,1];
inc(dian[0]);
dian[dian[0]]:=x;
ans:=0;
fillchar(bz,sizeof(bz),0);
bz[x]:=true;
while tot<n-1 do
begin
min:=maxlongint;
s:=0;
for i:=1 to len do
if not bz[a[i,2]] and (bz[a[i,1]])then
if a[i,3]<min  then
begin
min:=a[i,3];
s:=a[i,2];
end;
bz[s]:=true;
inc(tot);
ans:=ans+min;
inc(dian[0]);
dian[last[0]]:=x;
end;
writeln(ans);
end.
当然克鲁斯卡尔也能做,而且效率更高一些标程(kruskal):
var     a:array[0..10000,1..3]of longint;
map:array[1..100,1..100]of longint;
father:array[1..100]of longint;
n,i,j,k,l,ans,x,s,m,len,tot:longint;
procedure qsort(l,r:longint);
var     i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(l+r)div 2,3];
repeat
while a[i,3]<mid do inc(i);
while a[j,3]>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;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
function find(t:longint):longint;
var     x:longint;
begin
if father[t]=t then exit(t)
else
begin
x:=find(father[t]);
father[t]:=x;
exit(x);
end;
end;
begin
readln(n);
for i:=1 to n do
for j:=1 to n do
begin
read(map[i,j]);
if map[i,j]>0 then
begin
inc(len);
a[len,1]:=i;
a[len,2]:=j;
a[len,3]:=map[i,j];
end;
end;
qsort(1,len);
for i:=1 to n do
father[i]:=i;
tot:=0;
i:=1;
while tot<n-1 do
begin
j:=find(a[i,1]);
k:=find(a[i,2]);
if(j<>k)then
begin
father[j]:=k;
inc(tot);
ans:=ans+a[i,3];
end;
inc(i);
end;
writeln(ans);
end.

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  题解