PTA团体程序设计天梯赛-练习集 L2-024 部落(并查集)

    技术2025-08-14  37

    在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。

    输入格式: 输入在第一行给出一个正整数N(<= 104),是已知小圈子的个数。随后N行,每行按下列格式给出一个小圈子里的人: K P[1] P[2] … P[K] 其中K是小圈子里的人数,P[i](i=1, …, K)是小圈子里每个人的编号。这里所有人的编号从1开始连续编号,最大编号不会超过104。 之后一行给出一个非负整数Q(<= 104),是查询次数。随后Q行,每行给出一对被查询的人的编号。

    输出格式: 首先在一行中输出这个社区的总人数、以及互不相交的部落的个数。随后对每一次查询,如果他们属于同一个部落,则在一行中输出“Y”,否则输出“N”。

    输入样例: 4 3 10 1 2 2 3 4 4 1 5 7 8 3 9 6 4 2 10 5 3 7 输出样例: 10 2 Y N

    #include <bits/stdc++.h> using namespace std; int par[10010]; void init(int x){ for(int i = 1;i < x;i++){ par[i] = i; } } int find(int x){ if(par[x] == x) return x; return par[x] = find(par[x]); } int join(int x,int y){ x = find(x); y = find(y); if(x == y) return 0; else{ par[x] = y; return 1; } } int main(){ init(10010); int n,maxn = 0,sum = 0,a,b,k; vector<char> s; cin>>n; for(int i = 0;i < n;i++){ cin>>k; for(int j = 0;j < k;j++){ if(j == 0){ cin>>a; maxn = max(maxn,a); } else{ cin>>b; maxn = max(maxn,b); join(a,b); } } } for(int i = 1;i <= maxn;i++){ if(find(i) == i) sum+=1; } cout<<maxn<<" "<<sum<<endl; cin>>n; for(int i = 0;i < n;i++){ cin>>a>>b; if(find(a) == find(b)) cout<<"Y"<<endl; else cout<<"N"<<endl; } return 0; }
    Processed: 0.010, SQL: 9