MST最小生成树及Prim普鲁姆算法
MST在前面学习了Kruskal算法,还有一种算法叫做Prim的。这两者的区别是Prim算法适合稠密图,比如说鸟巢这种几乎所有点都有相连的图。其时间复杂度为O(n^2),其时间复杂度与边的数目无关;而kruskal算法的时间复杂度为O(eloge),跟边的数目有关,适合稀疏图。
prim算法
基本思想:假设G=(V,E)是连通的,TE是G上最小生成树中边的集合。算法从U={u0}(u0∈V),TE={ 空集 }开始。重复执行下列操作:
1.在所有u∈U,v∈V-U的边(u,v)∈E中找一条权值最小的边(u0,v0)并入集合TE中,同时v0并入U,直到V=U为止;接下里以 v0为边的起点,继续寻找权值最小的边并入集合TE中,依次往复;
2.最后,TE中必有n-1条边,T=(V,TE)为G的最小生成树。
Prim算法的核心:始终保持TE中的边集构成一棵生成树,也就是它与Kruskal算法的主要区别是,Prim是一直保持一种串联的状态而不遵从整体的贪心算法。其实初始点uo的选择可以随意,一般做题题目条件会给出或者取最小的权值边。
其实现的代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define infinity 1000000
#define max_vertexes 6
typedef int Graph[max_vertexes][max_vertexes];
void prim(Graph G,int vcount,int father[])
{
int i,j,k;
int lowcost[max_vertexes];
int closeset[max_vertexes],used[max_vertexes];
int min;
for (i=0;i<vcount;i++)
{
/* 最短距离初始化为其他节点到1号节点的距离 */
lowcost[i]=G[0][i];
/* 标记所有节点的依附点皆为默认的1号节点 */
closeset[i]=0;
used[i]=0;
father[i]=-1;
}
used[0]=1; /*第一个节点是在s集合里的*/
/* vcount个节点至少需要vcount-1条边构成最小生成树 */
for (i=1;i<=vcount-1;i++)
{
j=0;
min = infinity;
/* 找满足条件的最小权值边的节点k */
for (k=1;k<vcount;k++)
/* 边权值较小且不在生成树中 */
if ((!used[k])&&(lowcost[k]<min))
{
min = lowcost[k];
j=k;
}
father[j]=closeset[j];
printf("%d %d\n",j+1,closeset[j]+1);//打印边
used[j]=1;;//把第j个顶点并入了U中
for (k=1;k<vcount;k++)
/* 发现更小的权值 */
if (!used[k]&&(G[j][k]<lowcost[k]))
{
lowcost[k]=G[j][k];/*更新最小权值*/
closeset[k]=j;;/*记录新的依附点*/
}
}
} int main()
{
FILE *fr;
int i,j,weight;
Graph G;
int fatheer[max_vertexes];
for(i=0; i<max_vertexes; i++)
for(j=0; j<max_vertexes; j++)
G[i][j] = infinity;
fr = fopen("prim.txt","r");
if(!fr)
{
printf("fopen failed\n");
exit(1);
}
while(fscanf(fr,"%d%d%d", &i, &j, &weight) != EOF)
{
G[i-1][j-1] = weight;
G[j-1][i-1] = weight;
}
prim(G,max_vertexes,fatheer);
return 0;
}
邻接矩阵的形式进行存储的实现:
#include <stdio.h>
#define n 6
#define MaxNum 10000 /*定义一个最大整数*/ /*定义邻接矩阵类型*/
typedef int adjmatrix[n+1][n+1]; /*0号单元没用*/ typedef struct{
int fromvex,tovex;
int weight;
}Edge;
typedef Edge *EdgeNode; int arcnum; /*边的个数*/ /*建立图的邻接矩阵*/
void CreatMatrix(adjmatrix GA){
int i,j,k,e;
printf("图中有%d个顶点\n",n);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j){
GA[i][j]=0; /*对角线的值置为0*/
}
else{
GA[i][j]=MaxNum; /*其它位置的值置初始化为一个最大整数*/
}
}
}
printf("请输入边的个数:");
scanf("%d",&arcnum);
printf("请输入边的信息,按照起点,终点,权值的形式输入:\n");
for(k=1;k<=arcnum;k++){
scanf("%d,%d,%d",&i,&j,&e); /*读入边的信息*/
GA[i][j]=e;
GA[j][i]=e;
}
} /*初始化图的边集数组*/
void InitEdge(EdgeNode GE,int m){
int i;
for(i=1;i<=m;i++){
GE[i].weight=0;
}
} /*根据图的邻接矩阵生成图的边集数组*/
void GetEdgeSet(adjmatrix GA,EdgeNode GE){
int i,j,k=1;
for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
if(GA[i][j]!=0&&GA[i][j]!=MaxNum){
GE[k].fromvex=i;
GE[k].tovex=j;
GE[k].weight=GA[i][j];
k++;
}
}
}
} /*按升序排列图的边集数组*/
void SortEdge(EdgeNode GE,int m){
int i,j,k;
Edge temp;
for(i=1;i<m;i++){
k=i;
for(j=i+1;j<=m;j++){
if(GE[k].weight>GE[j].weight){
k=j;
}
}
if(k!=i){
temp=GE[i];GE[i]=GE[k];GE[k]=temp;
}
}
} /*利用普里姆算法从初始点v出发求邻接矩阵表示的图的最小生成树*/
void Prim(adjmatrix GA,EdgeNode T){
int i,j,k,min,u,m,w;
Edge temp;
/*给T赋初值,对应为v1依次到其余各顶点的边*/
k=1;
for(i=1;i<=n;i++){
if(i!=1){
T[k].fromvex=1;
T[k].tovex=i;
T[k].weight=GA[1][i];
k++;
}
}
/*进行n-1次循环,每次求出最小生成树中的第k条边*/
for(k=1;k<n;k++){
min=MaxNum;
m=k;
for(j=k;j<n;j++){
if(T[j].weight<min){
min=T[j].weight;m=j;
}
}
/*把最短边对调到k-1下标位置*/
temp=T[k];
T[k]=T[m];
T[m]=temp;
/*把新加入最小生成树T中的顶点序号赋给j*/
j=T[k].tovex;
/*修改有关边,使T中到T外的每一个顶点保持一条到目前为止最短的边*/
for(i=k+1;i<n;i++){
u=T[i].tovex;
w=GA[j][u];
if(w<T[i].weight){
T[i].weight=w;T[i].fromvex=j;
}
}
}
} /*输出边集数组的每条边*/
void OutEdge(EdgeNode GE,int e){
int i;
printf("按照起点,终点,权值的形式输出的最小生成树为:\n");
for(i=1;i<=e;i++){
printf("%d,%d,%d\n",GE[i].fromvex,GE[i].tovex,GE[i].weight);
}
} void main(){
adjmatrix GA;
Edge GE[n*(n-1)/2],T[n];
CreatMatrix(GA);
InitEdge(GE,arcnum);
GetEdgeSet(GA,GE);
SortEdge(GE,arcnum);
Prim(GA,T);
printf("\n");
OutEdge(T,n-1);
}
MST最小生成树及Prim普鲁姆算法的更多相关文章
- 经典问题----最小生成树(prim普里姆贪心算法)
题目简述:假如有一个无向连通图,有n个顶点,有许多(带有权值即长度)边,让你用在其中选n-1条边把这n个顶点连起来,不漏掉任何一个点,然后这n-1条边的权值总和最小,就是最小生成树了,注意,不可绕成圈 ...
- 查找最小生成树:普里姆算法算法(Prim)算法
一.算法介绍 普里姆算法(Prim's algorithm),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之 ...
- 最小生成树---普里姆算法(Prim算法)和克鲁斯卡尔算法(Kruskal算法)
普里姆算法(Prim算法) #include<bits/stdc++.h> using namespace std; #define MAXVEX 100 #define INF 6553 ...
- 图->连通性->最小生成树(普里姆算法)
文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可 ...
- 普利姆算法(prim)
普利姆算法(prim)求最小生成树(MST)过程详解 (原网址) 1 2 3 4 5 6 7 分步阅读 生活中最小生成树的应用十分广泛,比如:要连通n个城市需要n-1条边线路,那么怎么样建设才能使工程 ...
- ACM第四站————最小生成树(普里姆算法)
对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树. 普里姆算法是以其中某一顶点为起点,逐步寻找各个顶点上最小权值的边来构建最小生成 ...
- 最小生成树-普利姆算法lazy实现
算法描述 lazy普利姆算法的步骤: 1.从源点s出发,遍历它的邻接表s.Adj,将所有邻接的边(crossing edges)加入优先队列Q: 2.从Q出队最轻边,将此边加入MST. 3.考察此边的 ...
- 普里姆算法(Prim)
概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图(带权图)里搜索最小生成树.即此算法搜索到的边(Edge)子集所构成的树中,不但包括了连通图里的所有顶点(Vertex)且其所有边的权 ...
- HDU 1879 继续畅通工程 (Prim(普里姆算法)+Kruskal(克鲁斯卡尔))
继续畅通工程 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
随机推荐
- phpexcel导入数据库 基于thinkphp3.2
public function studentImportExcel(){ if (!empty ( $_FILES)){ $upload = new \Think\Upload(); ...
- 使用awstats统计分析tengine日志访问量及各种http网站数据
下载awstats最新安装包并解压 cd /usr/local/src wget http://www.awstats.org/files/awstats-7.3.tar.gz tar -zxvf a ...
- theano中的logisticregression代码学习
1 class LogisticRegression (object): 2 def __int__(self,...): 3 4 #定义一些与逻辑回归相关的各种函数 5 6 def method1( ...
- 在ios7真机上和iOS6模拟器上运行是好的,而在iOS6真机上运行却报错
在ios7真机上和iOS6模拟器上运行是好的,而在iOS6真机上运行却报错 解决方法: 或是都设置为yes.. Build Active Architecture Only的意思是只生成适应的指令集
- 玩SSH,SFTP
更改SFTP的本地路径,记得前面要加l哟,应该表示local的意思.如lls,lcd. 证书SSH更安全.就是多服务布置有些烦琐~~
- poj 2431 Expedition 贪心
简单的说说思路,如果一开始能够去到目的地那么当然不需要加油,否则肯定选择能够够着的油量最大的加油站加油,,不断重复这个贪心的策略即可. #include <iostream> #inclu ...
- wcf中的File-less Activation
File-less Activation Although .svc files make it easy to expose WCF services, an even easier approac ...
- Linux下文件轻松比对,自由开源的比较软件
文件比较工具用于比较计算机上的文件的内容,找到他们之间相同与不同之处.比较的结果通常被称为diff. diff同时也是一个基于控制台的.能输出两个文件之间不同之处的著名的文件比较程序的名字.diff是 ...
- bzoj3261
xor有一个很重要的性质就是A xor B xor B=A所以这道题求[l,r]中p,使a[p] xor a[p+1] xor ... xor a[N] xor x 最大就是=最大化a[1] xor ...
- BZOJ1599: [Usaco2008 Oct]笨重的石子
1599: [Usaco2008 Oct]笨重的石子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 758 Solved: 513[Submit][ ...