Some scientists took pictures of thousands of birds in a forest. Assume that all the birds appear in the same picture belong to the same tree. You are supposed to help the scientists to count the maximum number of trees in the forest, and for any pair of birds, tell if they are on the same tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive number N (≤104) which is the number of pictures. Then N lines follow, each describes a picture in the format:
K B1 B2 ... BK
where K is the number of birds in this picture, and Bi's are the indices of birds. It is guaranteed that the birds in all the pictures are numbered continuously from 1 to some number that is no more than 104.
After the pictures there is a positive number Q (≤104) which is the number of queries. Then Q lines follow, each contains the indices of two birds.
Output Specification:
For each test case, first output in a line the maximum possible number of trees and the number of birds. Then for each query, print in a line Yes
if the two birds belong to the same tree, or No
if not.
Sample Input:
4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7
Sample Output:
2 10
Yes
No
典型的普通并查集入门类型题,当时中午快吃饭之前瞄了一眼就大概知道应该怎么写,也是二十分钟就写出过了样例,交到PTA出现如下的结果
给我一下子整懵逼了,看了看parent数组,大小1e4+10,没错呀?花了两个小时的时间,对比了我和柳神的做法,终于是解决这道题,最后发现段错误仅仅是因为这个:
bool merge(int a,int b) {
int aa=fin(a);
int bb=fin(b);
if(aa!=bb) {
pre[aa]=bb;
}
}
当时我整个人懵逼了,因为之前在vj做各大oj的并查集题目时,我都是习惯性的把返回值定义成为bool,因为这样可以查询两个编号在不在一个并查集当中,而且不需要这个功能时,就可以不用写返回值。以前是从来没翻过车的,这回真的是让本菜鸡开了眼了,bool类型改成void类型后秒AC,有大神知道这是为嘛吗QAQ
![](/qrcode.jpg)
void merge(int a,int b) {
int aa=fin(a);
int bb=fin(b);
if(aa!=bb) {
pre[aa]=bb;
}
}
AC代码(大家可以试一试,只需要把void改成bool,25分秒变3分=_=)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+100;
int pre[maxn];
int n,m,num;
void init() {
for(int i=1; i<=maxn; i++) pre[i]=i;
}
int fin(int x) {
if(x==pre[x]) return x;
else return pre[x]=fin(pre[x]);
}
void merge(int a,int b) {
int aa=fin(a);
int bb=fin(b);
if(aa!=bb) {
pre[aa]=bb;
}
}
int main() {
init();
int ans=0,a,b,maxid=-1;
cin>>n;
for(int i=0; i<n; i++) {
cin>>num;
cin>>a;
maxid=a>maxid?a:maxid;
for(int j=1; j<num; j++) {
cin>>b;
maxid=b>maxid?b:maxid;
merge(a,b);
}
}
for(int i=1; i<=maxid; i++) {
if(fin(i)==i) ans++;
}
cout<<ans<<" "<<maxid<<endl;
cin>>m;
while(m--) {
cin>>a>>b;
if(fin(a)==fin(b)) printf("Yes\n");
else printf("No\n");
}
return 0;
}