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 (≤10^4) 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 (≤10^4) 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
题目大意:给出n幅画,每幅画里有k只鸟,一幅画里面的鸟都在同一棵树上。问有多少棵树和多少只鸟,再额外给出q次查询,每次查询两个不同标号的鸟是否在同一棵树上。
分析:由于输入的鸟的范围不超过10的4次方,可以用一个数组标记对应标号的鸟是否出现过,以及它们是出现在哪棵树上。
每次读入一组鸟,如果没有一只鸟出现过,则将它们全部标记为同一个值;如果有任意只鸟被标记过,则选取最小的值(可以是任意一个),将所有这一组的鸟,以及所有出现过的其它标记全部改为选定的最小标记值。完成读入后,遍历整个标记数组,输出出现的不同数字个数和它们的总数。对于每个查询,判断它们在标记数组内的值是否相等即可知道它们是否在同一棵树上。
举例:对于这一组
3
3 1 2 3
3 4 5 6
3 3 4 7
初始时将1,2,3全部标记为1;4,5,6全部标记为2;第三组输入时,找到3已经被标记为1,因此要将3,4,7全部标记为1,同时由于4已经被标记为2,还需要将原来所有被标记为2的全部改为1,即将4,5,6改为标记1.此时1,2,3,4,5,6,7全部被标记为1,即总共有1课树,7只鸟。
#include<algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <queue>
#include <stack>
#include <ctime>
#include <cmath>
#include <map>
#include <set>
#define INF 0xffffffff
#define db1(x) cout<<#x<<"="<<(x)<<endl
#define db2(x,y) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<endl
#define db3(x,y,z) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<endl
#define db4(x,y,z,r) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#r<<"="<<(r)<<endl
#define db5(x,y,z,r,w) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#r<<"="<<(r)<<", "<<#w<<"="<<(w)<<endl
using namespace std;
int main(void)
{
#ifdef test
freopen("in.txt","r",stdin);
//freopen("in.txt","w",stdout);
clock_t start=clock();
#endif //test
int n,cnt=1,sum=0;scanf("%d",&n);
int num[10010]={0};
for(int i=0;i<n;++i)
{
int a,temp=cnt,f=1;scanf("%d",&a);
int arr[a+5]={0};
for(int j=0;j<a;++j)
scanf("%d",&arr[j]);
for(int j=0;j<a;++j)
{
if(num[arr[j]]!=0)f=0,temp=num[arr[j]];
if(!f)break;
}
for(int j=0;j<a;++j)
{
if(num[arr[j]]==0)num[arr[j]]=temp;
else if(num[arr[j]]!=temp)
{
int id=num[arr[j]];
for(int l=0;l<10010;++l)
{
if(num[l]==id)num[l]=temp;
}
}
}
if(f)cnt++;
// db2(f,cnt);
}
int flag[10010]={0},ans=0;
for(int i=0;i<10010;++i)
{
if(num[i]&&flag[num[i]]==0)flag[num[i]]=1,ans++;
}
for(int i=0;i<10010;++i)
if(num[i])sum++;
printf("%d %d\n",ans,sum);
int k;scanf("%d",&k);
for(int i=0;i<k;++i)
{
int l,r;scanf("%d%d",&l,&r);
if(num[l]==num[r])printf("Yes\n");
else printf("No\n");
}
#ifdef test
clockid_t end=clock();
double endtime=(double)(end-start)/CLOCKS_PER_SEC;
printf("\n\n\n\n\n");
cout<<"Total time:"<<endtime<<"s"<<endl; //s为单位
cout<<"Total time:"<<endtime*1000<<"ms"<<endl; //ms为单位
#endif //test
return 0;
}