Description
若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的某个人所在家族的人数。
规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。
Input
第一行:三个整数n,(n<=100,000,m<=200,000),分别表示有n个人,m个信息。
以下m行:信息包含两种形式:
M a b:表示a和b具有亲戚关系。
Q a:要求输出a所在家族的人数。
Sample Input
5 10
M 3 2
Q 4
M 1 2
Q 4
M 3 2
Q 1
M 3 1
Q 5
M 4 2
Q 4
Sample Output
1
1
3
1
4
代码区:
#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
int s[100005],mark[100005];
int findd(int x)//查找函数,进行查找一个亲戚团体里的负责人
{
if(s[x]!=x)//当自己不是负责人的时候
s[x]=findd(s[x]);//递归调用函数找到自己亲戚团体的负责人
return s[x];
}
void unionn(int x,int y)
{
int a=findd(x);//a为x对应亲戚组织的负责人
int b=findd(y);//b为y对应亲戚组织的负责人
if(a!=b)//如果两个人不是亲戚(即两个人对应的亲戚团体负责人不相同
{
s[b]=a;//将其中一个组织归并到另一个组织里
mark[a]+=mark[b];//将两个亲戚组织人数相加
}
}
void init(int n)//初始化,将每人都属于一个亲戚团体,每人都是负责人
{
for(int i=1;i<=n;i++)
{
s[i]=i;
mark[i]=1;
}
}
int main()
{
int n,m;
while(cin >> n >> m)//输入人数以及信息组数
{
init(n);
for(int i=1;i<=m;i++)
{
int b1,b2;
char a;
cin >> a;
if(a=='M')//当遇到M时将两个人合并到一个团体里
{
cin >> b1 >> b2;
unionn(b1,b2);
}
else if(a=='Q')//当遇到Q时,将b1对应的负责人通过findd函数找出,并输出该亲戚团体的人数
{
cin >> b1;
cout << mark[findd(b1)] << endl;
}
}
}
return 0;
}
新手上路,有错请指正