问题
求连通图的最小生成树边权之和。
思路
将图的所有边按边权从小到大排序,从小到大枚举所有边。如果当前测试边的两个顶点位于两个不同的集合,则将该边和顶点加入到最小生成树中,并且累加其边权。当最小生成树的边数=定点数-1的时候,退出循环。此时的边权和即为所求。
注意点
1.此处使用结构体存储边的信息即可。包括两个顶点u,v。边权cost.
2.会用到sort排序
3.用到并查集和路径压缩的知识。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
const int maxe = 10010;
int n,m;
struct edge{
int u,v;
int cost;
}E[maxe];
bool cmp(edge a,edge b){
return a.cost<b.cost;
}
int father[maxn];
void init(){
for (int i = 0; i < maxn; ++i) {
father[i] = i;
}
}
int findFather(int x){
int a = x;
while(x!=father[x]){
x = father[x];
}
while(a!=father[a]){
int z = a;
a = father[a];
father[z] = x;
}
return x;
}
int kruskal(int n,int m){
int ans=0,num_edges=0;
init();
sort(E,E+m,cmp);
for (int i = 0; i < m; ++i) {
int faA = findFather(E[i].u);
int faB = findFather(E[i].v);
if(faA!=faB){
father[faA] = faB;
ans = ans + E[i].cost;
++num_edges;
}
if(num_edges == n-1)
break;
}
return ans;
}
int main(){
cin>>n>>m;
int u,v,cost;
for (int i = 0; i < m; ++i) {
cin>>u>>v>>cost;
E[i].u = u;
E[i].v = v;
E[i].cost = cost;
}
int ans = kruskal(n,m);
cout<<ans<<endl;
return 0;
}
总结
kruskal算法适合边稀疏的图