生成树 口袋的天空

版权声明:未经本蒟蒻同意,请勿转载本蒻博客 https://blog.csdn.net/wddwjlss/article/details/82228385

这么水的题,复习的时候居然没有立刻想出来。
题意:给出一张图的关系, n 个点, m 条边,问能否分成k个联通块,求最小边权和。

最小边权和,意味着每一个联通块都是一棵树,考虑最小生成树的过程,边权从小到大排序,一开始有 n 个联通块,每一次合并减少一个联通块,当联通块数量 = k b r e a k 。所有边枚举完后如果联通块数 > k ,就无法分成 k 个联通块。

#include<bits/stdc++.h>
using namespace std;
int n,m,k,f[1001000],num,ans;
struct node
{
    int x,y,c;
}e[1001000];
int find(int x)
{
    if(x==f[x])
        return x;
    else
    {
        f[x]=find(f[x]);
        return f[x];
    }
}
bool cmp(node n1,node n2)
{
    return n1.c<n2.c;
}
int main()
{
    cin>>n>>m>>k;
    num=n;
    for(int i=1;i<=m;++i)
        scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].c);
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=n;++i)
        f[i]=i;
    for(int i=1;i<=m;++i)
    {
        if(num==k)
            break;
        int fx=find(e[i].x);
        int fy=find(e[i].y);
        if(fx!=fy)
        {
            ans+=e[i].c;
            num--;
            f[fx]=fy;
        }
    }
    if(num!=k)
        cout<<"No Answer";
    else
        cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wddwjlss/article/details/82228385
今日推荐