Prim算法:
从一个节点出发, 每次找到连接的边, 找到最小权重的边, 将边连接的节点加入集合, 找出集合中所有点连接的边, 在寻找最小边, 知道所有点都被找到.
将图存储在邻接矩阵中.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3fffffff;
const int maxn = 10001;
int n, m;
int graph[maxn][maxn]; //将图存储在邻接矩阵中
int lowcost[maxn]; //记录邻接点的最短边
int visit[maxn]; //标记
void readin(){
scanf("%d%d", &n, &m);
int a, b, c;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
graph[i][j] = INF;
for(int i = 1; i <= m; ++i){
scanf("%d%d%d", &a, &b, &c);
graph[a][b] = c;
graph[b][a] = c;
}
}
void init(int start){
for(int i = 1; i <= n; ++i){
lowcost[i] = graph[start][i];
visit[i] = 0;
}
}
int prim(int start)
{
int ans = 0;
int min;
init(start);
visit[start] = 1;
for(int i = 1; i <= n; ++i){
min = INF;
int flag = -1;
for(int j = 1; j <= n; ++j){ //找到最小值
if(!visit[j] && min > lowcost[j]){
min = lowcost[j];
flag = j;
}
}
if(flag != -1){
cout << min <<endl;
visit[flag] = 1;
ans += min; //权值叠加
for(int j = 1; j <= n; ++j){ //更新lowcost
if(!visit[j] && graph[flag][j] < lowcost[j]){
lowcost[j] = graph[flag][j];
}
}
}
}
return ans;
}
int main()
{
readin();
int ans = prim(1);
cout << ans <<endl;
return 0;
}
/*
5 6
1 2 1
2 3 2
1 3 2
1 4 3
4 3 5
4 5 3
*/