Prime算法
先找随意一个起点,找一个与其他点相连的边中的最小的边,此时这两个点缩成1个点,继续以上步骤。用vis数组判定是否在集合内再加入。
具体是指在每加入一个点时就要将这个点的所有边都加入到原集合内,并且不断地取出最短边判断是否可以利用后再添加。
对于每次取最短边的方法可以使用优先队列。
对于“边结构体”记得重载一遍运算符以使之边的长度由小到大排列,否则需要在优先队列中修改第三个参数。
struct edge{
int nd;
int nex;
int len;
bool operator <(const edge &a) const{
return len > a.len;
}
}e[10005];
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
对于无向图要加两遍边,而有向图只需要一遍。
add(a, b, c);
add(b, a, c);
- 1
- 2
算法部分:
int Prim(int x, int n){
int tot = 1;
int sum = 0;
priority_queue<edge> q;
while(tot < n){
vis[x] = 1;
for(int i = id[x]; ~i; i = e[i].nex){
if(vis[e[i].nd])
continue;
q.push(e[i]);
}
while(!q.empty()){
edge v = q.top();
q.pop();
if(vis[v.nd])
continue;
else{
sum += v.len;
x = v.nd;
tot++;
break;
}
}
}
while(!q.empty()) q.pop();
return sum;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
完整代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int cnt;
int id[10005];
bool vis[10005];
struct edge{
int nd;
int nex;
int len;
bool operator <(const edge &a) const{
return len > a.len;
}
}e[10005];
void init(int n){
for(int i = 0; i <= n; i++){
id[i] = -1;
}
memset(e, 0, sizeof(e));
memset(vis, 0, sizeof(vis));
cnt = 0;
}
void add(int bgn, int nd, int len){
e[cnt].nd = nd;
e[cnt].len = len;
e[cnt].nex = id[bgn];
id[bgn] = cnt++;
}
int Prim(int x, int n){
int tot = 1;
int sum = 0;
priority_queue<edge> q;
while(tot < n){
vis[x] = 1;
for(int i = id[x]; ~i; i = e[i].nex){
if(vis[e[i].nd])
continue;
q.push(e[i]);
}
while(!q.empty()){
edge v = q.top();
q.pop();
if(vis[v.nd])
continue;
else{
sum += v.len;
x = v.nd;
tot++;
break;
}
}
}
while(!q.empty()) q.pop();
return sum;
}
int main(){
int n, m;
while(scanf("%d %d", &n, &m) && m){
int a, b, c;
init(m);
for(int i = 0; i < n; i++){
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
int ans = Prim(1, n);
cout << ans << endl;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
转载自 http://blog.csdn.net/crazyforsaken/article/details/79125333