prim 最小生成树优先队列实现

1 篇文章 0 订阅

prim 最小生成树优先队列实现 

#include<iostream>
#include<vector>
#include<queue>
#include<set>
using namespace std;

int N,M;
struct node{
	int to,len;
	node(){}
	node(int to,int len):to(to),len(len){}
};

struct qnode{
	int from, to,len;
	qnode(){}
	qnode(int from,int to,int len):from(from),to(to),len(len){}
	bool operator <(const qnode & b) const{
		return len>b.len;
	} 
};
const int MAXN = 10000;
const int INF = 0x3f3f3f3f;
vector<node> map_[MAXN]; 

void add_edge(int a,int b,int cost){
	map_[a].push_back(node(b,cost));
	map_[b].push_back(node(a,cost));
}
int ans;
int dist[MAXN];
set<pair<int,int> > sets;
void prim(){
	ans = 0;
	fill(dist,dist+N,INF);
	dist[0] = 0;
	priority_queue<qnode> que;
	que.push(qnode(-1,0,0));
	while(!que.empty()){
		qnode temp = que.top(); que.pop();
		if(temp.len != dist[temp.to]) continue;
		ans+=dist[temp.to];
		if(temp.from > temp.to)
			sets.insert(make_pair(temp.to,temp.from));
		else{
			sets.insert(make_pair(temp.from,temp.to));
		}
		for(int i=0;i<map_[temp.to].size();i++){
			node nnode = map_[temp.to][i];
			if(dist[nnode.to] > nnode.len){
				dist[nnode.to] = nnode.len;
				que.push(qnode(temp.to,nnode.to,nnode.len));
			}
		}
	}
}

int main(){
	scanf("%d%d",&N,&M);
	for(int i=0;i<M;i++){
		int a,b,len;
		scanf("%d%d%d",&a,&b,&len);
		add_edge(a,b,len);
	}
	prim();
	printf("%d\n",ans);
	set<pair<int,int> >:: iterator it = sets.begin();
	for(;it!=sets.end();it++){
		printf("%d-->%d\n",it->first,it->second);
	}
	return 0;
} 

输入: 

6 10
0 1 4
0 4 1
0 5 2
1 2 6
1 5 3
2 3 6
2 5 5
3 4 4
3 5 5
4 5 3

输出 :由于没有指定开始顶点,所以就默认从0号节点开始,-1可以理解为不存在

15
-1<-->0
0<-->4
0<-->5
1<-->5
2<-->5
3<-->4

对比 dijkstra算法:

https://blog.csdn.net/Willen_/article/details/100358199

其实两者的思路都是相同的,唯一的不同在于,设置的

公共的dist[MAXN] 距离数组的含义不同:

dijkstra中,表达的是对于源点的 的距离对于其他点来说

prim中,表达的是对于这个整体集合的距离,所以可以看到在dijkstra中的松弛操作稍稍改动一下就是prim算法了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值