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