7-156 部落 (25分)
输入样例:
4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7
输出样例:
10 2
Y
N
思路
利用并查集方法即可,具体见AC代码:
#include<bits/stdc++.h>
#define inf 11000
using namespace std;
int p[inf],c[inf];
int find(int x){ //找到x的部落首领
if(x==p[x]) return x;
return p[x]=find(p[x]);
}
void merge(int x, int y){
int xx=find(x), yy=find(y);
if(xx!=yy) p[yy]=xx; //如果两个部落首领,则合为一个部落,即都是xx做首领
}
int main(){
int n,k,q,a,b,sum=0,maxx;
for(int i=1; i<inf; i++) p[i]=i; //初始化
cin>>n;
while(n--){
cin>>k>>a;
maxx=a;
for(int i=1; i<k; i++){
cin>>b;
merge(a,b);
maxx=max(maxx,b);
}
sum=max(sum,maxx);//找到最大编号,即社区总人数
}
for(int i=1; i<=sum; i++){
p[i]=find(i); //更新
c[p[i]]++; //将编号为p[i]的部落首领的部落人数加加,即统计每个部落人数
}
int cnt=0;
for(int i=1; i<=sum; i++){
if(c[i]>0) cnt++; //统计部落个数
}
cout<<sum<<" "<<cnt<<endl;
cin>>q;
while(q--){
cin>>a>>b;
if(find(a)==find(b)) cout<<"Y\n"; //如果这两个人的部落首领相同,则是一个部落的
else cout<<"N\n";
}
return 0;
}
欢迎大家批评改正!!!