题意:
在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。
思路:
一个非常裸的并查集吧,注意连完边后再遍历一遍确定把边都连上了,再继续查询操作
代码:
#include<bits/stdc++.h>
#include<sstream>
#include<unordered_map>
#define endl '\n'
using namespace std;
const int maxn=10005;
int p[maxn],a[maxn];
int findx(int x)
{
if(p[x]!=x)
{
return p[x]=findx(p[x]);
}
else {
return p[x];
}
}
unordered_map<int ,int >mo;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,i,j,k,t,cnt=0,cnt1=0,q;
cin>>n;
for(i=1;i<maxn;i++) p[i]=i;
for(i=0;i<n;i++)
{
cin>>k;
int t=-1,d;
for(j=0;j<k;j++)
{
cin>>d;
if(mo[d]==0){
mo[d]++;
cnt++;
}
if(t==-1) {
t=d;
}
else {
int m1=findx(t);
int m2=findx(d);
if(m1!=m2)
{
p[m2]=m1;
}
}
}
}
mo.clear();
for(i=1;i<=cnt;i++)
{
p[i]=findx(p[i]);
if(mo[p[i]]==0) cnt1++;
mo[p[i]]++;
}
cin>>q;
cout<<cnt<<" "<<cnt1<<endl;
for(i=0;i<q;i++)
{
int u,v;
cin>>u>>v;
if(findx(u)!=findx(v))
{
cout<<"N"<<endl;
}
else {
cout<<"Y"<<endl;
}
}
return 0;
}