正题
大意
有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);
}