问题
求最小生成树的边权之和
思路
参考dijkstra算法的思路,更改d[]的含义,并且更新d[]的条件有一些不同。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000;
const int INF = 1000000000;
int d[maxn];
int G[maxn][maxn];
bool vis[maxn] = {false};
int n,m;
int prim(){ //默认0号为初始结点
fill(d,d+maxn,INF);
d[0] = 0;
fill(vis,vis + maxn, false);
int ans = 0;
for (int i = 0; i < n; ++i) {
int u = -1,MIN = INF;
for (int j = 0; j < n; ++j) {
if(vis[j] == false && d[j]<MIN){
u = j;
MIN = d[j];
}
}
if(u == -1)return -1;
vis[u] = true;
ans = ans + d[u];
for (int v = 0; v < n; ++v) {
if(vis[v] == false && G[u][v] != INF && d[v] > G[u][v]){
d[v] = G[u][v];
}
}
}
return ans;
}
int main(){
cin>>n>>m;
int c1,c2,L;
fill(G[0],G[0]+maxn*maxn,INF);
for (int i = 0; i < m; ++i) {
cin>>c1>>c2>>L;
G[c1][c2] = G[c2][c1] = L;
}
int ans = prim();
cout<<ans<<endl;
return 0;
}
总结
prim算法和dijkstra算法思想非常相似,不同点在于prim中的d[]用来存储各顶点到集合S的最小距离。dijkstra用d[]来存储各顶点和起点的最短距离。prim算法中,默认使用0号结点作为初始结点,适用于边稠密的图。