经典最小生成树prim与kruskal算法分析比较

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

经典最小生成树prim与kruskal算法分析比较

例题

农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,

并连接到所有的农场。当然,他需要你的帮助。

约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。

为了用最小的消费,他想铺设最短的光纤去连接所有的农场。

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

纤最短的方案。

输入格式 Input Format

输入格式经常会以两中形式

(1)采用邻接矩阵存储

第一行为农场的个数,N(3<=N<=100)。

接下去为一个N*N的矩阵,表示每个农场之间的距离。(农场之间的距离小于999,

0路线表示无法直接到达)。

(2)图采用边目录方式存储。

第一行N为农场的个数,M为农场与农场之间共有M条可以搭设光纤路线。

接下去的M行为中每行有3个数A,B,C。分别表示农场A到农场B的距离为B。

输出格式 Output Format

输出连接所有农场并所用光纤最短的方案。 (输出之后要求换行)

样例输入 Sample Input

(1)采用邻接矩阵存储。 (2)采用边目录方

式存储。

6

6 7

0 3 0 0 0 2 1

2 3

3 0 5 0 2 0 2 3 5

0 5 0 1 0 0 3 4 1

0 0 1 0 4 0 4 5 4

0 2 0 4 0 1 2 5 2

2 0 0 0 1 0 6 5 1

1 6 2

样例输出 Sample Output

(1)采用邻接矩阵存储(2)采用边目录方式存储。

10 10

(1)我的prim的代码采用邻接矩阵存储

prim适合采用邻接矩阵存储代码如下

var n,i,j,w,k,t,w1,m,min,p:longint;

ch:char;

lowcost,coset:array[1..100]of longint;

bo:array[1..100]of boolean;

map:array[1..100,1..100]of longint; {邻接矩阵图}

begin

while not eof do

begin

readln(n);

if n=0 then break;

for i:=1 to n do

for j:=1 to n do //初始化

begin

read(map[i,j]);

if (i=j)or(map[i,j]=0)then

map[i,j]:=maxlongint; //把不相连的点之间设为无穷大

end;

for i:=1 to n do

begin

lowcost[i]:=map[1,i];

coset[i]:=1;

bo[i]:=false;

{初始化lowcost集合(即每个点到集合的最短距离)与bo数组和 coset(设这个点为A)到集合内于他连接的且最短距离的另一个点(这个点为b)

那么coset就是记录与点A的父亲节点B(B一定要具备上述条件)} end;

bo[1]:=true;

m:=0;

for i:=1 to n-1 do

begin

min:=maxlongint;

for j:=1 to n do

if (bo[j]=false)and(lowcost[j]

集合距离最短的点

begin

min:=lowcost[j];p:=j;

end;

writeln('(',coset[p],',',p,')'); //输出上一步得到的与集合距离啊短距离的点的父亲节点和该点(即集合新选择的最短路径);

m:=m+min; //把上一步得到的点到集合的距离不断累加

bo[p]:=true; //把以加入的集合的点设为true,防止重判.

for j:=1 to n do

if (bo[j]=false)and(map[p,j]

begin

lowcost[j]:=map[p,j]; //重判集合到那一些还每被选入集合的点的距离

coset[j]:=p; //刷新父亲节点

end;

end;

writeln(m);

end;

end.

(2)我的kruskal的代码采用边目录方式存储

kruskal适合采用边目录方式存储。

(kruskal的一般版本);

在这里说明一下感染和完全感染的区别以便于理解下面的代码的注释

[感染指一条边中只有一个点被感染了要么是起点,要么是始点,一边中的两点中只有一点被感染称为感染]

[完全感染染指一边中两点都被感染了,只有两点同时都被感染了才称为完全感染。如果该边的两点被完全感染那么这条边也就被完全感染(即false),而没有被完全感染的边或感染的边都为(true)]

解析的不好不要BS我水平有限

type edge=record

x,y,c:longint;

end;

var n,m,i,j,mincost,min,p:longint;

d:array[1..100] of boolean;

e:array[1..100]of boolean;

elist:array[1..100] of edge;

begin

while not eof do

相关文档
最新文档