Prim & Kruskal Algorithm
2017-06-10 16:59
162 查看
**Prim算法**
Prim算法是图论中的一种算法,可在加权连通图里搜索最小生成树。此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。
中文名:
普里姆算法
提出时间: 1930年
外文名: Prim Algorithm
应用学科: 计算机,数据结构,数学(图论)
别称: 最小生成树算法
适用领域范围: 应用图论知识的实际问题
算法:贪心
/[b]**********************************************************[/b]/
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 ,dis ,visited ; 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 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 9 1 2 28 1 6 10 6 5 25 5 7 24 5 4 22 7 4 18 4 3 12 3 2 16 7 2 14 **/
相关文章推荐
- zoj 1914 || poj 2349 Arctic Network【最小生成树 kruskal && prim】
- hdoj 1875 畅通project再续【最小生成树 kruskal && prim】
- Prim&Kruskal
- Prim's minimum spanning tree algorithm
- HDU 1863--畅通工程【Prim && kruskal】
- 最小生成树 Kruskal&&Prim
- poj 1258 Agri-Net 【Prim&Kruskal】
- HDOJ 1233 还是畅通工程 最小生成树 kruskal && prim
- POJ 1258 Agri-Net 最小生成树 prim && kruskal
- zoj 1203 Swordfish 【最小生成树 kruskal && prim】
- 51Nod 1212 无向图最小生成树(最小生成树Kruskal & Prim
- hdoj 1162 Eddy's picture【最小生成树 kruskal && prim】
- hdoj 1863 畅通工程【最小生成树,kruskal&&prim】
- hdu 1301 Jungle Roads &&poj 1251 (prim 或者kruskal)
- 最小生成树(prim&&kruskal)
- HDU 1223--还是畅通工程【prim && kruskal】
- 【算法复习】图的最小生成树(Prim&Kruskal)
- hdoj 2122Ice_cream’s world III 【最小生成树 kruskal && prim】
- HDU-#1102 Constructing Roads(Prim & Kruskal)
- hdu 3371 Connect the Cities【kruskal&prim】