学习笔记——浅谈Kuskal最小生成树算法
思想:
Kuskal(克鲁斯卡尔)算法(以下简称K算法)主要用于求最小生成树,实现方法是通过并查集。
首先,将每一个点看作一个集合,随后对它进行排序(使用sort),排序的内容是边的权值,将边权小的边优先连起来。
如果这条边连着不同的集合,就将这条边加入最小生成树,并将两个点看作同一个集合。
但是,如果这两条边连着不同的集合,就忽略这条边,继续遍历下一条边。
众所周知,有n-1条边的联通图称为树,所以遍历到n-1条边为止。
描述:
1.初始化并查集,令fa[x]=x
2.令tot=0(tot是最小生成树的边权之和)
3.将所有边权排序
4.计数器k=0
5.循环枚举所有从小到大排序的边,当它的两点u,v不属于同一集合时,合并并加入最小生成树
6.tot+=W(u,v),k++
7.当k=n+1时,break
典中典:
P2820
说白了就是最小生成树的经典板子,我们用K算法表示
要求用网线联通的最大值,我们可以用它的总值减去最小生成树tot
int main() { //freopen("net.in","r",stdin); //freopen("net.out","w",stdout); n=read(),k=read(); for (int i=1;i<=n;i++) { fa[i]=i; } for (int j=1;j<=k;j++) { l[j].from=read(),l[j].to=read(),l[j].num=read(); ans+=l[j].num; } int a,b; sort(l+1,l+1+k,cmp); for (int i=1;i<=k;i++) { //cout<<"0"<<endl; a=find(l[i].from); b=find(l[i].to); if (a==b) { continue; } sum+=l[i].num; fa[a]=b; x++; if(x==n) { break; } } cout<<ans-sum<<endl; return 0; }

浙公网安备 33010602011771号