【算法】Prim算法最小生成树

一,算法分析

Prim算法简述
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:V new= {x},其中x为集合V中的任一节点(起始点),E new= {},为空;
3).重复下列操作,直到V new= V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合V new中的元素,而v不在V new集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合V new中,将<u, v>边加入集合E new中;
4).输出:使用集合V new和E new来描述所得到的最小生成树。

二,代码

#include<iostream>
#define MAX 1000000
using namespace std;


int main(){
	int min = MAX;
	int points =6;
	int edges = 10;
	int edge[points][points];
	int dis=0;//最短距离数组 
	int flag[points]={0};//是否经过数组 
	
	//初始化数组 
	for(int i = 0;i<points;i++){
		for(int j = 0;j<points;j++){
			edge[i][j]=MAX;
		}
	}
	
	cout<<"请输入位置距离关系:"<<endl;
	 
	int p1,p2,w;
	for(int i=0;i<edges;i++){
		cin>>p1>>p2>>w;
		edge[p1][p2]=w;
		edge[p2][p1]=w;
	}
	
	flag[0]=1;
	for(int count=0; count<points-1;count++){//points-1次对点搜索 
	   int min_i = 0;
	   int min_k = 0;
	   for(int k = 0;k<points;k++){//对所有在visited最短距离数组中才进行查找最短距离 
		   if(flag[k]==1){
		    //如果属于最短距离数组 
		    	for(int i = 0;i<points;i++){//对在最短距离数组里的每一个点查找最短距离 
		    		if(min>edge[k][i]&&flag[i]==0){
		    		min = edge[k][i];
		    		min_k = k; 
		    		min_i = i;
		     		} 
		    	}
		   	}
	    }
	  	
	    	flag[min_i] = 1; 
	     	dis +=min;
	     	cout<<min_k<<"--"<<min_i<<endl;
	     	edge[min_k][min_i]=MAX;
	     	edge[min_i][min_k]=MAX;
	     	min = MAX;//每次查找完,将min恢复为MAX 
	  
	 }
	 cout<<"最短距离:"<<dis;
		
}

在这里插入图片描述

三,算法效率

Prim算法分析:

使用邻接矩阵来保存图的话,时间复杂度是O(V^2)。
在每一遍V-1次迭代中,都要遍历实现优先队列的数组,来查找并删除距离最小的顶点,如果有必要再更新余下顶点的优先级。
如果图是用邻接链表表示的,并且优先队列是由最小堆实现的,该算法的运行时间属于 O ( ∣ E ∣ l o g ∣ V ∣ ) O(|E|log|V|) O(ElogV).因为该算法执行了|V|-1次删除最小元素的操作,并且进行了|E|次验证,如有必要,还要对一个规模不大于|V|的最小堆改变其元素的优先级,运行时间属于 ( ∣ V ∣ − 1 + ∣ E ∣ ) O ( l o g ∣ V ∣ ) = O ( ∣ E ∣ l o g ∣ V ∣ ) (|V|-1+|E|)O(log|V|) = O(|E|log|V|) (V1+E)O(logV)=O(ElogV)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值