7-2 看照片找基友 (20分)
小A是个单身狗,他有很多好基友,他们平时喜欢出去聚会和旅游,每次聚会都会照一张集体照上传到群共享,有一天,小A整理照片,想通过照片来看看他们这群基友的情况。我们假定,在同一张照片里同时出现的,两两之间都是好基友,基友的基友也是好基友。那么问题来了,你能帮小A确定任意的两个人是否好基友吗?
输入格式:
首先输入照片的张数N(N<10000),之后N行,按以下格式输入照片里的情况:
K P1 P2 P3 …… PK
其中K是照片中的人数,后面的K个数是照片中人的编号,我们假定从1开始连续编号,人数不超过10000。 接下来输出查询的个数T(T<10000),之后T行,每行输入两个数,分别是查询的两个人的编号。
输出格式:
首先输出基友圈的个数和所有人数,之后对T组查询,在一行中输出查询结果,如果两个是好基友,输出Yes,否则输出No。
输入样例:
在这里给出一组输入。例如:
4
3 11 1 2
3 3 4 10
4 1 5 7 8
3 9 6 12
2
10 5
7 11
输出样例:
在这里给出相应的输出。例如:
3 12
No
Yes
作者
胡伟平
单位
广西科技大学
代码长度限制
16 KB
时间限制
150 ms
内存限制
笔记:这道题主要考并查集,整体上不难。但是我一共交了不下二十次(就差颁发最佳拼搏奖了@-@),一直卡在最后一个测试点,检查代码也没看出来哪错了(崩溃边缘徘徊)。最后重新理解了一下题目,发现我将人数主观理解了,题目明确讲到 “我们假定从1开始连续编号,人数不超过10000。”,我直接将它设定为我们输入的人数。
这个道题深刻的告诉我一定要 认真看题,切勿主观认为。
正确代码:
#include<iostream>
#include<map>
#include<stdio.h>
#include<map>
using namespace std;
int count,ans=0;
int s[20005];
void init(){
for(int i=0;i<10005;i++){
s[i]=i;
}
}
int find(int x){
if(s[x]==x){
return x;
}
else{
s[x]=find(s[x]);
return s[x];
}
}
int merge(int a,int b){
int a1=find(a);
int b1=find(b);
if(a1!=b1){
s[a1]=b1;
ans++;
}
}
int main(){
int t,n,k;
while(cin>>n){
ans=0;
count=0;
int a,b;
map<int,int>mp;
init();
while(n--){
cin>>k;
for(int i=0;i<k;i++){
cin>>b;
if(i==0){
a=b;
}
if(b>count) count = b;//看清题目, 后面的K个数是照片中人的编号
merge(a,b); // 我们假定从1开始连续编号,人数不超过10000
}
}
cin>>t;
ans=count-ans;
if(mp[1]==0) count+1;
cout<<ans<<" "<<count<<endl;
while(t--){
cin>>a>>b;
if(find(a)==find(b)){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
}
return 0;
}
*/