上海专业做网站公网站建设公司官网
文章目录
- 题目解读
- 输入格式
- 输出格式
- 思路
- Ac Code
- 参考
题目解读
我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。
输入格式
第一行给出一个正整数N(≤104),是已知小圈子的个数。
随后N行,每行按一下格式给出一个小圈子里的人:
K P[1] P[2] ⋯ P[K] 其中K是小圈子里的人数,P[i](i=1,⋯,K)是小圈子里每个人的编号。这里所有人的编号从1开始连续编号,最大编号不会超过104 。
之后一行给出一个非负整数Q,随后Q行,每行给出一对儿被查询的人的编号
输出格式
首先在一行中输出这个社区的总人数、以及互不相交的部落的个数。随后对每一次查询,如果他们属于同一个部落,则在一行中输出Y,否则输出N。
思路
使用并查集,将每个圈子的第一个人作为父节点,在合并集合的过程当中,统计人的个数,最后根节点的个数就是圈子的个数,而查询是否属于同一个圈子是并查集的基本应用
Ac Code
#include<bits/stdc++.h>using namespace std;//最多这么多人
const int N = 1e4+10;
int f[N];//先写并查集板子
int find(int u){if(f[u]!=u)f[u]=find(f[u]);return f[u];
} void merge(int a,int b){int aa=find(a),bb =find(b);if(aa!=bb)f[aa]=bb;
}bool judge(int a,int b){return find(a)==find(b);
}int main(){int n;cin >> n;map<int,bool> mp;//存储状态 for(int i=0; i<N; i++)f[i]=i;for(int i=0; i<n; i++){int k;cin >> k;int fa;for(int j=0; j<k; j++){if(j==0){cin>>fa;if(mp.count(fa)==0)mp[fa]=1;}else{int x;cin >> x;if(mp.count(x)==0)mp[x]=1;merge(x,fa);}} }cout<<mp.size()<<" ";int res=0;for(int i=0; i<N; i++){//这个人需要先存在 if(mp.count(i) != 0 && f[i]==i)res++;} cout<<res<<endl;int q;cin >> q;while(q--){int a,b;cin >> a >> b;if(judge(a,b))cout<<"Y";else cout<<"N";cout << endl;} return 0;
}
参考
B站up主,一天能吃五顿饭
🌻编写本篇文章目的是笔者想以输出的形式进行学习,顺便记录学习点滴🌻
🌹 如果本篇文章对你有帮助的话那就点个赞吧👍🌹
😇 本篇文章可能存在多处不足,如有修改意见,可以私信或者评论我哦 😇