Prim & Kruskal Algorithm
来源:互联网 发布:大数据与经济发展 编辑:程序博客网 时间:2024/05/20 01:34
**Prim算法**
Prim算法是图论中的一种算法,可在加权连通图里搜索最小生成树。此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。
中文名:
普里姆算法
提出时间: 1930年
外文名: Prim Algorithm
应用学科: 计算机,数据结构,数学(图论)
别称: 最小生成树算法
适用领域范围: 应用图论知识的实际问题
算法:贪心
/**********************************************************/
Prim算法的描述
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起点),Enew= {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边 (u,v),其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将(u, v)边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。- 时间复杂度:
通过邻接矩阵图表示的简易实现中,找到所有最小权边共需O(V)的运行时间。使用简单的二叉堆与邻接表来表示的话,普里姆算法的运行时间则可缩减为O(ElogV),其中E为连通图的边数,V为顶点数。如果使用较为复杂的斐波那契堆,则可将运行时间进一步缩短为O(E+VlogV),这在连通图足够密集时(当E满足Ω(VlogV)条件时),可较显著地提高运行速度。
http://blog.csdn.net/zenail501129/article/details/23551909
http://blog.csdn.net/u014488381/article/details/41447229
#include <stdio.h>#include <cstdlib>#include<memory.h>const int Max =0x7fffffff;const int N=50;int n;int g[N][N],dis[N],visited[N];int prim(){ int i,j; int pos,min; int ans=0; memset(visited,0,sizeof(visited)); visited[1]=1;pos=1; //assign a value to the dis[N] first for(i=2;i<=n;i++) dis[i]=g[pos][i]; for(i=1;i<n;i++) { min=Max; for(j=1;j<=n;j++) { if(visited[j]==0&&min>dis[j]) { min=dis[j]; pos=j; } } printf("The node being traversed is :%d\n",pos); ans+=min; printf("The value of ans is %d\n",ans); //mark the node visited[pos]=1; //update the weight for(j=1;j<=n;j++) if(visited[j]==0&&dis[j]>g[pos][j]) dis[j]=g[pos][j]; } return ans;}int main(){ int i=1,j=1; int ans=0; int w; printf("Please enter the number of the nodes:\n"); scanf("%d",&n); for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(i==j) g[i][j]=0; else g[i][j]=Max; } printf("Please enter the number of the edges:\n"); int edgenum; scanf("%d",&edgenum); int v1,v2; printf("Please enter the number and the corresponding weight:\n"); for(i=1;i<=edgenum;i++) { scanf("%d%d%d",&v1,&v2,&w); g[v1][v2]=g[v2][v1]=w; } ans=prim(); printf("The sum of the weight of the edges is:%d\n",ans); system("pause"); return 0;}
Kruskal Algorithm
#include<stdio.h>#include<stdlib.h>#include<iostream>using namespace std;#define MAXN 11 //顶点个数的最大值#define MAXM 20 //边的个数的最大值struct edge //边{ int u, v, w;}edges[MAXM]; //边的数组int parent[MAXN]; //parent[i]为顶点i所在集合对应的树中的根结点int n, m; //顶点个数、边的个数int i, j; //循环变量void UFset() //初始化{ for(i = 1; i <= n; i++) parent[i] = -1;}int Find(int x) //查找并返回结点x所属集合的根结点{ int s; //查找位置 for(s = x; parent[s] >=0; s = parent[s]) ; while(s != x) //优化方案——压缩路径,使后续的查找操作加速 { int tmp = parent[x]; parent[x] = s; x = tmp; } return s;}//运用并查集,将两个不同集合的元素进行合并,使两个集合中任意两个元素都连通void Union(int R1, int R2){ int r1 = Find(R1), r2 = Find(R2); //r1和r2分别为R1和R2的根结点 int tmp = parent[r1] + parent[r2]; //两个集合结点数之和(负数) //如果R2所在树结点个数 > R1所在树结点个数(注意parent[r1]是负数) if(parent[r1] > parent[r2]) { parent[r1] = r2; parent[r2] = tmp; } else { parent[r2] = r1; parent[r1] = tmp; }}int cmp(const void *a, const void *b) //实现从小到大的比较函数{ edge aa = *(const edge *)a, bb = *(const edge *)b; return aa.w-bb.w;}void Kruskal(){ int sumweight = 0; //生成树的权值 int num = 0; //已选用的边的数目 UFset(); //初始化parent数组 for(i = 0; i < m; i++) { if(Find(edges[i].u) != Find(edges[i].v)) { printf("%d %d %d\n", edges[i].u, edges[i].v, edges[i].w); sumweight += edges[i].w; num++; Union(edges[i].u, edges[i].v); } if(num >= n-1) break; } printf("The weight of MST is : %d\n", sumweight);} main(){ scanf("%d%d", &n, &m); //读入顶点个数和边数 for(int i = 0; i < m; i++) scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w); //读入边的起点和终点 printf("The edges chosen are :\n"); qsort(edges, m, sizeof(edges[0]), cmp); //对边按权值从小到大排序 Kruskal();}/**7 91 2 281 6 106 5 255 7 245 4 227 4 184 3 123 2 167 2 14**/
- Prim & Kruskal Algorithm
- Prim Kruskal
- Kruskal&&prim
- Kruskal&Prim
- Prim&Kruskal
- kruskal&&prim
- Kruskal algorithm
- prim algorithm
- Kruskal Prim Dijkstra
- Kruskal Prim Dijkstra
- poj2485 kruskal与prim
- ZOJ 1914 Prim Kruskal
- Prim算法+Kruskal算法
- prim + kruskal 实现
- poj1258Agri Net Kruskal+prim
- hdu 1863(prim&kruskal)
- HDU1879(水Kruskal、Prim)
- poj2421【MST-prim+Kruskal】
- 虚函数
- shell-commands
- java中的占位符
- bzoj 1051简单tarjan
- CLR via C# 读书笔记 6-2 不同AppDomain之间的通信
- Prim & Kruskal Algorithm
- [bzoj2038][2009国家集训队]小Z的袜子(hose) 莫队算法
- 第七章 为什么巴比伦塔会失败
- shell-keys
- [leetcode]583. Delete Operation for Two Strings
- 我对servlet的理解
- TLC59731 LED 驱动芯片 C语言驱动程序
- 三张图片了解activity进出场动画
- Iptables简介与示例