1 solutions
-
2
A1389 亲戚
经典并查集,无他,唯手熟尔
题干
【题目描述】
若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的某个人所在家族的人数。
规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。
【输入】
第一行:三个整数n,(n≤100,000,m≤200,000),分别表示有n个人,m个信息。
以下m行:信息包含两种形式:
M a b:表示a和b具有亲戚关系。
Q a:要求输出a所在家族的人数。
【输出】
要求输出a所在家族的人数。
【输入样例】
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
【输出样例】
1 1 3 1 4
【来源】
一本通在线评测
【样例分析】
一共5个人,10组关系
3,2是亲戚 此时1家族:1 2家族:2,3 4家族:4 5家族:5 4家族只有4一个人
1,2是亲戚 此时1家族:1,2,3 4家族:4 5家族:5 4家族只有4一个人
3,2是亲戚 已经属于同一集合 1家族有1,2,3三个人
3,1是亲戚 已经属于同一集合 5家族只有5一个人
2,4是亲戚 此时1家族:1,2,3,4 5家族:5 4家族有1,2,3,4四个人
代码+解析:
#include<bits/stdc++.h> using namespace std; int n,m,fa[285714],nf[285714];//与A1387一致,我们可以用一个数组统计家族人数 int Get(int x){ return x==fa[x]?x:fa[x]=Get(fa[x]); } void Merge(int x,int y){ fa[Get(x)]=Get(y); }// 并查集基本函数(见A1346) int main(){ char start; cin>>n>>m; for(int i=1;i<=n;i++){ nf[i]=1; fa[i]=i;//初始化 } for(int i=1;i<=m;i++){ cin>>start; for(int i=0;i<=n;i++){ if(Get(i)!=i){ nf[Get(i)]+=nf[i]; nf[i]=0;//每轮循环开始都归并一次(见A1387) } } if(start=='M'){ int a,b; cin>>a>>b; Merge(a,b);// 并集操作 } else{ int a; cin>>a; cout<<nf[Get(a)]<<endl;// 输出 } } return 0;// 自信递交!!! }
涉及题目 A1346校外 A1346校内 A1387校外 A1387校内
点赞,懂?
- 1
Information
- ID
- 874
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 22
- Accepted
- 9
- Uploaded By