蒟蒻第一篇题解,写得可能不大尽如人意,
望大佬指点蒟蒻的题解,多谢。
我个人认为这道题就是Kruskal算法的模板题,还是比较简单的。
Kruskal(克鲁斯卡尔):一种巧妙利用并查集来求最小生成树的算法。
实现过程:
过程大致如下:
- 初始化,将并查集初始化,每个点的父节点为其本身。
- 计数器归零。
- 把所有边的权值从小到大快排。
- 具体的Kruskal算法:
1 for(int i=1;i<=m;i++) 2 { 3 int f1=Find(e[i].x),f2=Find(e[i].y); 4 if(f1!=f2) 5 { 6 ans=max(ans,e[i].dis); 7 fa[f1]=f2; 8 if(k==n-1) break; 9 k++; 10 } 11 }
完整代码如下(有一丢丢注解)
code
#include<bits/stdc++.h> using namespace std; int n,m,ans,k=1,fa[100005]; struct node//用结构体表示边 { int x,y,dis; }e[100005]; bool cmp(node x,node y) { return x.dis<y.dis; } int Find(int x)//查找x的祖宗 { if(fa[x]!=x) fa[x]=Find(fa[x]); return fa[x]; } void Union(int x,int y)//将x,y并为一个集合 { if(Find(x)!=Find(y)) fa[Find(x)]=Find(y); } int main() { cin>>n>>m; for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) cin>>e[i].x>>e[i].y>>e[i].dis; sort(e+1,e+m+1,cmp);//快排 for(int i=1;i<=m;i++) { int f1=Find(e[i].x),f2=Find(e[i].y); if(f1!=f2)//如果祖宗不同 { ans=max(ans,e[i].dis);//更新答案 fa[f1]=f2; if(k==n-1) break;//至少连点数-1条边 k++;//计数器++ } } cout<<ans<<endl;//输出 return 0; }