ssl2342-打击犯罪【并查集】

正题

大意

有n个犯罪团伙,他们之间可以相互联系,按照1到n的顺序打击,求最少打击多少个犯罪团伙可以使多个犯罪团伙组成的已经无法与外联系的团伙最大的那个不超过n/2。

解题思路

先储存每条连接的路径,然后从n枚举到1,连接它扩展出去的边,直到最大的那个大于n/2就好了

代码

#include<cstdio>
using namespace std;
int k,l[1001][1001],n,father[1001],lt[1001];
bool flag,v[1001];
int find(int x)
{
    if (father[x]!=x) return father[x]=find(father[x]);
    return father[x];
}
void unionn(int x,int y)
{
    int fa=find(x),fb=find(y);
    if (fa==fb || !v[x] || !v[y]) return;
    if (fa<fb)
    {   
        father[fb]=fa;
        lt[fa]+=lt[fb];//计算个数
    }
    else
    {
        father[fa]=fb;
        lt[fb]+=lt[fa];
    }
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&l[i][0]);
        for (int j=1;j<=l[i][0];j++)
        {
            scanf("%d",&l[i][j]);
        }
        lt[i]=1;
        father[i]=i;
        v[i]=false;
    }
    for (int i=n;i>=1;i--)
    {
        v[i]=true;//设置为可以联通
        for (int j=1;j<=l[i][0];j++)
        {
            unionn(i,l[i][j]);//向外扩张
        }
        flag=true;
        for (int j=1;j<=n;j++)
        {
            if (lt[j]>n/2) flag=false;
        }
        if (!flag)//已经大于
        {
            k=i;
            break;
        }
    }
    printf("%d",k);
}
    原文作者:犯罪团伙问题
    原文地址: https://blog.csdn.net/Mr_wuyongcong/article/details/79674455
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞