描述
知道“人言可畏”吗?在我们的生活中,尤其在现有的网络上,存在一些广泛传播的谣言。今天我们在一个群体中研究这个问题:
(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; }