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
其实两者的思路都是相同的,唯一的不同在于,设置的
公共的dist[MAXN] 距离数组的含义不同:
dijkstra中,表达的是对于源点的 的距离对于其他点来说
prim中,表达的是对于这个整体集合的距离,所以可以看到在dijkstra中的松弛操作稍稍改动一下就是prim算法了