社会关系网络
时间限制(普通/Java) : 1000 MS/ 3000 MS 运行内存限制 : 65536 KByte比赛描述
现代社会通信便捷,借助于Internet形成了各式各样的社区,每个人都可能属于多个社交圈,尤其是Facebook类社交网站的出现,使世界缩小了,人与人的交往扩大了频繁了。sed同学正在做这方面的毕业设计课题,指导老师给他布置了一个任务:已知一群人的社会关系网络,判断两个人之间的关系,他们是否可以通过社交圈的人相互结识。
输入
第一行包括三个整数:n、 m、k,分别表示人数、社区数、查询两个人之间的关系的用例数 (1 ≤ n ≤ 10000, 0 ≤ m ≤ 100,1 ≤ k ≤ 100)。
m行,每行首先给出一个社区的人数,然后给出代表人的序号。
k行,每行给出待查询的两个人(用序号表示)。
输出
输出k行,每行给出两个人(用序号表示)、YES或NO, YES表示这两个人可以通过社交圈的人相互结识,NO表示不能。
注意:输出部分的结尾要求包含一个多余的空行。
样例输入
3 1 2
2 1 2
0 1
1 2
样例输出
0 1 NO
1 2 YES
题目来源
“IBM南邮杯”个人赛2009
题目链接:http://acm.njupt.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1075
题目分析:裸并查集
#include <cstdio>
#include <cstring>
int const MAX = 20000;
int father[MAX];
int n, m, k;
void UFset()
{
for(int i = 1; i <= n; i++)
father[i] = i;
}
int Find(int n) //压缩路径
{
return n == father[n] ? n : father[n] = Find(father[n]);
}
void Union(int R1, int R2) //合并
{
int r1 = Find(R1);
int r2 = Find(R2);
father[r1] = r2;
}
int main()
{
scanf("%d %d %d", &n, &m, &k);
UFset();
for(int i = 0; i < m; i++)
{
int num;
scanf("%d", &num);
if(num == 1 || num == 0)
continue;
int fir;
scanf("%d", &fir);
for(int i = 1; i < num; i++)
{
int get;
scanf("%d", &get);
Union(fir, get);
}
}
for(int i = 0; i < k; i++)
{
int a, b;
scanf("%d %d", &a, &b);
if(Find(a) == Find(b))
printf("%d %d YES\n", a, b);
else
printf("%d %d NO\n", a, b);
}
}