什么是最小生成树?
1.关键词---生成树
1)没有环
2)包括图结构的所有点
说人话:有n个顶点的图结构,其边的个数为n - 1
2.关键词--最小
边的权值和最小的生成树
3.最小生成树场景
城市间连接光缆,铺设光缆的最小成本,每两个城市之间都要有光缆
如何构建最小生成树---什么是克鲁斯卡尔算法?
目标是达到权值和最小,克鲁斯卡尔是直接选择权值最小的边,prim是从顶点出发,间接找最小权值边,稀疏图用克鲁斯卡尔方法比较方便
算法步骤模板
1)将所有边按权重从小到大排序
2)枚举每一条边 a,b权重c
if a,b不相通 <1>
则将这条边加入集合
<1>:相通即图结构有环
题目链接:859. Kruskal算法求最小生成树 - AcWing题库
c++代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;
int n,m,p[N];
struct Edge{
int a,b,w;
}e[M];
bool cmp(Edge a,Edge b)
{
return a.w < b.w;
}
int find(int x)//并查集模板
{
if(p[x] != x)
p[x] = find(p[x]);
else
return p[x];
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++ )
p[i] = i;
for(int i = 0; i < m; i ++ )
{
int a,b,w;
cin >> a >> b >> w;
e[i] = {a,b,w};
}
sort(e,e + m,cmp);//<2>sort用法
int res ,cnt;
res = cnt = 0;
for(int i = 0; i < m; i ++ )
{
int a = e[i].a,b = e[i].b,w = e[i].w;
a = find(a),b = find(b);
if(a != b)//如果这条边的加入不会产生环,即这两点不连通,则把这条边加入集合
{
p[a] = b;
res += w;
cnt ++;
}
}
if(cnt < n-1)
puts("impossible");
else
cout << res << endl;
return 0;
}
<2>:sort函数:sort(begin,end,cmp)
该处用sort给结构体排序