本题很明显是个并查集的问题,并查集主要就两个函数,find()和merge(),寻找根的函数和合并函数,若根相同则属于同个集合,不需要合并,若根不同,则需要进行合并。
#include<iostream>
using namespace std;
int parent[10001]={0};
int find(int i){ // 查找编号i所在的集合的根
while (parent[i]>0) i=parent[i];
return i;
}
void merge(int i,int j){
//根的parent里面存的是该集合的个数
if (parent[i]<parent[j]){
parent[i]+=parent[j];
parent[j]=i;
}
else{
parent[j]+=parent[i];
parent[i]=j;
}
}
int main()
{
int n;
cin>>n;
while (n--){
int k;
cin>>k;
int *p=new int[k];
cin>>p[0];
if (parent[p[0]]==0) parent[p[0]]=-1;
for (int i=1; i<k; i++){
cin>>p[i];
if (parent[p[i]]==0) parent[p[i]]=-1;
int x,y;
x=find(p[i-1]); y=find(p[i]);
if (x!=y) merge(x,y);
}
delete[]p;
}
int c1,c2; // c1表示总人数,c2表示部落个数
c1=c2=0;
for (int i=1; i<10001; i++){
if (parent[i]<0) c2++;
if (parent[i]!=0) c1++;
else break;
}
cout<<c1<<" "<<c2<<endl;
int q;
cin>>q;
while (q--){
int x,y;
cin>>x>>y;
if (find(x)!=find(y)) cout<<"N\n";
else cout<<"Y\n";
}
return 0;
}