学习笔记——浅谈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;
}

 

posted @ 2022-07-18 19:40  美索maysoul  阅读(94)  评论(0)    收藏  举报