Prim算法与Kruskal算法探索
来源:互联网 发布:c语言leap什么意思 编辑:程序博客网 时间:2024/05/29 19:34
以前以为自己用的生成最小生成树的方法是Prim算法,今天自己拜读了《数据结构与算法分析》之后才知道自己有多愚蠢,原来以前一直用的是KrusKal算法。。。。。。
今天好好说道说道这两个算法:
KrusKal算法用于稀疏图,贪心策略,连续的按照最小的权值选择边。
Prim算法用于稠密图,也是贪心策略,每次取离小生成树最近的点作为生成树的心点,并入生成树内生成新的小生成树,知道所有节点均被纳入生成树后结束。
这两种方法均可得到点点之间路径最短的联通图。
例如这个例子:
用Prim算法的过程:
用KrusKal算法的过程:
下面我编码来实现Prim算法:
(测试数据均是图一)
- #include<stdio.h>
- #include<string.h>
- #define INF 0x11111110
- int map[2010][2010],Tree[2010];
- int closeset[2010];//节点依附的点(就是与生成树里那个点链接)
- int lowcost[2010];//节点到生成树的最短距离
- int sum=0;
- void Prim(int n)
- {
- int i,j,k;
- int min;
- Tree[1]=1;//先把 1放在生成树里
- for(i=1;i<=n;i++)
- {
- lowcost[i]=map[i][1];//所有节点与生成树的最短距离初始化
- closeset[i]=1;//i依附于谁 (初始化都依附于1)
- }
- for(j=1;j<=n-1;j++)//n个节点有n-1条边
- {
- min=INF;
- //找到离生成树最近的点
- for(i=1;i<=n;i++)
- {
- if(!Tree[i]&&lowcost[i]<min)
- {
- min=lowcost[i];
- k=i;
- }
- }
- printf(”链接%d %d 距离为%d\n”,k,closeset[k],min);
- sum+=min;
- Tree[k]=1; //把 k并入生成树
- //找到离新加入的点最近的点,更新那个点距生成树的距离
- for(i=1;i<=n;i++)
- {
- if(!Tree[i]&&map[k][i]<lowcost[i])
- {
- lowcost[i]=map[k][i];//更新最小值
- closeset[i]=k;//记录新的依附点
- }
- }
- }
- }
- int main()
- {
- int i,j,n,m,x,y,z;
- while(scanf(“%d %d”,&n,&m)!=EOF)
- {
- memset(Tree,0,sizeof(Tree));//用来记录节点是否在生成树中
- memset(map,INF,sizeof(map));
- for(i=0;i<m;i++)
- {
- scanf(”%d %d %d”,&x,&y,&z);
- map[x][y]=z;
- map[y][x]=z;
- }
- printf(”生成树的合成顺序:\n”);
- Prim(n);
- printf(”生成树的最短距离:%d\n”,sum);
- }
- return 0;
- }
#include<stdio.h>
输入:
7 12
1 4 1
1 2 2
1 3 4
2 4 3
2 5 10
3 4 2
3 5 6
6 4 8
6 7 1
5 4 7
5 7 6
7 4 4
输出:
生成树的合成顺序:
链接4 1 距离为1
链接2 1 距离为2
链接3 4 距离为2
链接7 4 距离为4
链接6 7 距离为1
链接5 3 距离为6
生成树的最短距离:16
下面我编码来实现KrusKal算法:
- #include<iostream>
- #include<algorithm>
- using namespace std;
- struct node
- {
- int a,b;
- int len;
- }per[5000];
- int cmp(node x,node y)
- {
- if(x.len!=y.len) return x.len<y.len;
- }
- int main()
- {
- int i,sum,n,m,num;
- int flag[200];
- while(scanf(“%d %d”,&n,&m),n!=0)
- {
- for(i=0;i<m;i++)
- {
- scanf(”%d%d%d”,&per[i].a,&per[i].b,&per[i].len);
- }
- sort(per,per+m,cmp);
- for(i=1;i<=n;i++) flag[i]=1;
- flag[per[0].a]=0;
- sum=0;
- for(i=0;i<m;i++)
- {
- num=flag[per[i].a]+flag[per[i].b];
- if(num==1)
- {
- printf(”链接%d %d 长度%d\n”,per[i].a,per[i].b,per[i].len);
- sum+=per[i].len;
- flag[per[i].a]=flag[per[i].b]=0;
- i=0;
- }
- }
- printf(”生成树路径总和%d\n”,sum);
- }
- return 0;
- }
#include<iostream>#include<algorithm>using namespace std;struct node{ int a,b; int len;}per[5000];int cmp(node x,node y){ if(x.len!=y.len) return x.len<y.len;}int main(){ int i,sum,n,m,num; int flag[200]; while(scanf("%d %d",&n,&m),n!=0) { for(i=0;i<m;i++) { scanf("%d%d%d",&per[i].a,&per[i].b,&per[i].len); } sort(per,per+m,cmp); for(i=1;i<=n;i++) flag[i]=1; flag[per[0].a]=0; sum=0; for(i=0;i<m;i++) { num=flag[per[i].a]+flag[per[i].b]; if(num==1) { printf("链接%d %d 长度%d\n",per[i].a,per[i].b,per[i].len); sum+=per[i].len; flag[per[i].a]=flag[per[i].b]=0; i=0; } } printf("生成树路径总和%d\n",sum); } return 0;}
输入
7 12
1 4 1
1 2 2
1 3 4
2 4 3
2 5 10
3 4 2
3 5 6
6 4 8
6 7 1
5 4 7
5 7 6
7 4 4
输出:
链接6 7 长度1
链接7 4 长度4
链接1 4 长度1
链接3 4 长度2
链接1 2 长度2
链接5 7 长度6
生成树路径总和16
区别一目了然……..
阅读全文
0 0
- Prim算法与Kruskal算法探索
- 【算法小总结】Prim算法与Kruskal算法探索
- Prim算法+Kruskal算法
- Prim算法 Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- Prim算法 Kruskal算法 简述
- Prim算法和Kruskal算法
- prim 算法和 kruskal算法
- Prim算法和Kruskal算法
- Prim算法和Kruskal算法
- js中保证小数为固定的位数
- 在一个修改了数据的事务被提交之前,Oracle进行了以下操作
- Apache Spark 2.2.0 中文文档
- Effective Java(避免使用最终方法、覆盖equals时请遵守通用约定)
- ibatis 传递复杂参数
- Prim算法与Kruskal算法探索
- 【PL/SQL】用星号拼出金字塔
- py2exe打包pyside项目时出错
- js基础-JSON
- 博客简介
- Linux下快速安装Ruby
- 【PostgreSQL-9.6.3】临时表
- springMVC返回jsp和html的配置,已经springmvc返回html乱码的解决方案
- iText导出pdf、word、图片