【题目链接】
https://www.patest.cn/contests/gplt/L2-024
题目意思
在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。
解题思路
利用并查集来规划每个部落,用set来求总人数和部落数。
代码部分
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<set>
using namespace std;
#define INF 0x3f3f3f
const int maxn=1e4+5;
int pre[maxn];
int vis[maxn];
int n,m;
void init()
{
for (int i=1;i<maxn;i++)
pre[i]=i;
}
int unions(int root) ///查询最高父亲节点
{
int son,tmp;
son=root;
while(root!=pre[root])
root=pre[root];
while(son!=root) ///压缩路径
{
tmp=pre[son];
pre[son]=root;
son=tmp;
}
return root;
}
void join(int root1,int root2) ///合并
{
int x,y;
x=unions(root1);
y=unions(root2);
if (x!=y)
pre[x]=y;
}
int main()
{
set<int>sum;
int s=0;
cin>>n;
init();
for (int i=0;i<n;i++)
{
cin>>m;
for (int j=0;j<m;j++)
{
int root1,root2;
cin>>root2;
sum.insert(root2);
if (j==0)
root1=root2;
else
{
join(root1,root2);
root1=root2;
}
}
}
cin>>m;
set<int>::iterator it;
for (it=sum.begin();it!=sum.end();it++)
{
if (*it==pre[*it])
s++;
}
cout<<sum.size()<<' '<<s<<endl;
for (int i=0;i<m;i++)
{
int t1,t2;
cin>>t1>>t2;
if (unions(t1)==unions(t2))
cout<<"Y"<<endl;
else cout<<"N"<<endl;
}
return 0;
}