描述
知道“人言可畏”吗?在我们的生活中,尤其在现有的网络上,存在一些广泛传播的谣言。今天我们在一个群体中研究这个问题:
(1)一个群体中存在一些两两之间的朋友关系;
(2)一个人发布“谣言”;
(3)一个人在知道“谣言”时,会告诉他(她)的朋友;
请你判断是否所有人最终都知道谣言。
输入
第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括多行:
l 第1行给出两个整数(空格分隔),前者表示群体人数n,后者表示“谣言”发布者t,群体成员用整数序号表示,2≤n≤200,0≤t≤n-1
l 第2行给出一个整数,群体两两存在的朋友关系数m,0≤m≤20100
l m行,每行两个整数(空格分隔),表示群体中两个成员存在朋友关系。
输出
对于每个测试用例:
l 所有人最终都知道谣言则输出“Yes”,否则输出“No”
注意:输出部分的结尾要求包含一个多余的空行。
样例输入
2
3 0
2
0 1
0 2
4 0
2
0 1
2 3
样例输出
Yes
No
题目来源
算法与数据结构设计考核赛2009
代码:
#include<cstdlib>
#include<iostream>
#include<cstdio>
using namespace std;
class UFSet
{
public:
UFSet(int mSize);
~UFSet(){delete[]parent;}
int Find2(int i);
void Union2(int x, int y);
int *parent;
private:
int size;
};
UFSet::UFSet(int mSize)
{
size=mSize;
parent=new int[size];
for (int i=0;i<size; i++) parent[i]=-1;
}
int UFSet::Find2(int i)
{
int r,t,l;
for (r=i;parent [r]>=0; r=parent[r]);
if (i!=r)
for (t=i;parent [t]!=r; t=l){
l=parent[t]; parent[t]=r;
};
return r;
}
void UFSet::Union2( int x,int y)
{
int temp=parent[x]+parent[y];
if (parent[x]>parent[y])
{
parent[x]=y; parent[y]=temp;
}
else
{
parent[y]=x;parent[x]=temp;
}
}
int main()
{
int i,j;
int temp1,temp2;
scanf("%d",&i);
for(j=0;j<i;j++)
{
int n,t,m,p,a,b;
scanf("%d %d",&n,&t);
UFSet x=n;
scanf("%d",&m);
for(p=0;p<m;p++)
{
scanf("%d %d",&a,&b);
temp1=x.Find2(a);
temp2=x.Find2(b);
if(temp1!=temp2)
x.Union2(temp1,temp2);
}
temp1=x.Find2(t);//找到t所在的数的根节点的序号,然后赋值给temp1
temp2=x.parent[temp1];//将temp1的parent域的值赋给temp2
if(temp2==-n)printf("Yes\n");
else printf("No\n");
}
return 0;
}