最小生成树 普利姆算法
#include <bits/stdc++.h>
using namespace std;
// 定义line结构,一条边的2个端点(x,y) 和权重 quan
struct line{
int x;
int y;
int quan;
};
// 自定义比较器,按quan 升序排列
bool cmp(line& a, line& b){
return a.quan < b.quan;
}
vector<line> ls(100); // 存储边
vector<int> g(100); // 并查集
// 并查集 找父节点
int ufind(int x){
if(g[x] == x){
return g[x];
}
g[x] = ufind(g[x]);
return g[x];
}
int main() {
int n,m; // n:点数量[1,n], m:边数量 [x ,y ,q]
cin >> n >> m;
for(int i = 1;i <= m; i++){// 读入边的两个端点和权重
cin >> ls[i].x >> ls[i].y >> ls[i].quan;
}
sort(ls.begin() +1, ls.begin() +1+m, cmp);// 按权重升序
for(int i = 1; i <= n; i++){// 初始化并查集
g[i] = i;
}
int k = 0;//加入的边的个数
int dis = 0;// 总消耗
for(int i = 1;i <=m; i++){
// ls排完序了,根据权重从小到大
// 先取出的权重最小
// 先出来的两个点加入到同一个集合中
// 1.如果两个点已经在同一个集合中了,不合并了
// 2.合并前期可能有 1 - 2 ; 3 - 4 -5 两个集合这种情况
// 那么先让这个两个集合分别合并
// 之后一定有一次,两个集合中的点会有两个点,让他们产生交集
int gx = ufind(ls[i].x);
int gy = ufind(ls[i].y);
// 两个点已经在集合中了 说明已经在树上了,合并
// 只要两个点不是同一个集合,那么就将它们合并
if(gx != gy){
g[gy] = gx;
k++;
dis += ls[i].quan;
}
if(k > n-1){break;} // 最少的边已经到了,所以break;
}
cout << dis;
return 0;
}
测试用例:
5 7
1 2 3
1 3 2
2 3 1
2 4 1
3 4 4
4 5 2
3 5 5
预期输出:6

浙公网安备 33010602011771号