【USACO】Agri-Net最短网络(最小生成树)

来源:互联网 发布:linux tmp 手动清理 编辑:程序博客网 时间:2024/06/11 17:03

农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。

约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。

每两个农场间的距离不会超过100000


PROGRAM NAME: agrinet


INPUT FORMAT














第一行:农场的个数,N(3<=N<=100)。第二行..结尾:后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。


SAMPLE INPUT (file agrinet.in)


4

0 4 9 21

4 0 8 17

9 8 0 16

21 17 16 0


OUTPUT FORMAT


只有一个输出,其中包含连接到每个农场的光纤的最小长度。


SAMPLE OUTPUT (file agrinet.out)


28


这一道题的解法是最小生成树:

下面介绍两种最小生成树的算法:

第一种:

由于要连接到所有的农场,那么从任意一个农场出发都可以找到最小解。

进入循环:

1、先查找与新开辟的点直接连接的所有连法。

2、在所有已经开辟的点中查找最小长度的连法且符合条件(不形成环,用标记记录一下就好了)。

3、连接这个点,记录经过的路径。

直到选了N-1条路后即可停止。

第二种:

对所有的路径进行排序,取最小的解且这个解符合条件。这个时候,就有一个新的知识点了。那就是并查集。对于两个集合合并的时候,如果一个个标记,时间复杂度会很高。对于解法在此文中暂不阐述。将最小点连接。取完N-1条边的时候,这就是最小解。


对于第一种解法的代码:

var        ans,i,n,m,p,min,x,y,z,sum,j:longint;        b:array[1..10000,1..2] of longint;        bz:array[1..10000] of boolean;        a:array[1..100,1..100] of longint;procedure find(k:longint);var        i:longint;begin        for i:=1 to n do          begin            if ((bz[i]=false) or (bz[k]=false)) and (a[k,i]>0) then              begin                inc(p);                b[p,1]:=k;                b[p,2]:=i;              end;          end;end;begin        read(n);        for i:=1 to n do          for j:=1 to n do            begin              read(a[i,j]);            end;        fillchar(bz,sizeof(bz),false);        p:=0;        find(1);        sum:=1;        while (sum<n) do          begin            min:=0;            for i:=1 to p do              begin                if ((bz[b[i,1]]=false) or (bz[b[i,2]]=false)) and ((min=0) or (a[b[i,1],b[i,2]]<a[b[min,1],b[min,2]])) then                  min:=i;              end;            ans:=ans+a[b[min,1],b[min,2]];            find(b[min,2]);            bz[b[min,2]]:=true;            bz[b[min,1]]:=true;            inc(sum);          end;        writeln(ans);end.


阅读全文
0 0
原创粉丝点击