您的位置:首页 > 其它

1118. Birds in Forest (25)

2017-12-31 14:32 411 查看


1118. Birds in Forest (25)

时间限制

150 ms

内存限制

65536 kB

代码长度限制

16000 B

判题程序

Standard

作者

CHEN, Yue

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


题意:科学家在森林里拍了一些照片,同一张照片上的鸟住在同一棵树上,求出一共有几棵树,几只鸟,并对某两只鸟是否在同一棵树上进行回答。

分析:并查集,自己做完以后再看别人的代码发现 我做的有点复杂

           别人的思路:每行输入N个数,每输入一个就把他们合并成一棵树,然后输出

           我的思路 :输入N个数,找到N个数中 最小的根,然后把N个数合并

           意思都是那个意思,但是思维上感觉他们的更简单自然一些

代码:(对应我的思路)

#include<iostream>
#include<vector>
using namespace std;
int num[10010]={0};
int cnt[10010]={0};
int find_root(int n){
while(num
!= n)
n=num
;
return n;
}
int main()
{
int n,m,q,k,tmp;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>m;
vector<int> list(m);
for(int j=0; j<m; j++){
cin>>list[j];
if(!num[list[j]]) num[list[j]] = list[j];
}
int min=find_root(list[0]);
for(int j=0; j<m; j++)
if(find_root(list[j]) < min) min = find_root(list[j]);
for(int j=0; j<m; j++)
num[find_root(num[list[j]])] = min;
}
int trees=0,birds=0;
for(int i=0;i<10010;i++)
{
if(num[i] && !cnt[find_root(num[i])]){
trees++;
// cout<<"第"<<trees<<"颗树,它是"<<num[i]<<",它的根是"<<find_root(num[i])<<endl;
cnt[num[i]]=num[i];
}
if(num[i])
birds++;
}
cout<<trees<<" "<<birds<<endl;
int a,b;
cin>>q;
for(int i=0;i<q;i++)
{
cin>>a>>b;
if(find_root(a) == find_root(b)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}

结尾:写完de了20分钟的bug吧,找出来四五个没有加find_root的地方。因为写的时候是对照样例写的,所以有的地方直接就用num[],没想那么多。并查集的合并一定要从根来合并,下次写的时候应该写一个union的函数,这样看起来会清晰很多。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PAT 并查集 合并