prim 最小生成樹優先隊列實現

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算法了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章