谣言传播

http://acm.njupt.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1131

  • Description

知道“人言可畏”吗?在我们的生活中,尤其在现有的网络上,存在一些广泛传播的谣言。今天我们在一个群体中研究这个问题:

(1)一个群体中存在一些两两之间的朋友关系;

(2)一个人发布“谣言”;

(3)一个人在知道“谣言”时,会告诉他(她)的朋友;

请你判断是否所有人最终都知道谣言。

  • Input

第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括多行:

l 第1行给出两个整数(空格分隔),前者表示群体人数n,后者表示“谣言”发布者t,群体成员用整数序号表示,2≤n≤200,0≤t≤n-1

l 第2行给出一个整数,群体两两存在的朋友关系数m,0≤m≤20100

l m行,每行两个整数(空格分隔),表示群体中两个成员存在朋友关系。

  • Output

对于每个测试用例:

l 所有人最终都知道谣言则输出“Yes”,否则输出“No”

注意:输出部分的结尾要求包含一个多余的空行。

  • Sample Input

2
3 0
2
0 1
0 2
4 0
2
0 1
2 3

  • Sample Output

Yes
No

#include<iostream>
using namespace std;
#define min(x,y)((x)<(y)?(x):(y))
int par[201];
int Find(int i)
{
    int r,t,l;
    for(r=i;par[r]!=r;r=par[r]);
    if(i!=r)
        for(t=i;par[t]!=r;t=l)
        {
            l=par[t];
            par[t]=r;
        };
    return r;
}
void link(int x,int y)
{
    int a,b;
    int Max,Min;
    a=Find(x);
    b=Find(y);
    Min=(a<b)?a:b;
    Max=a+b-Min;
    par[Max]=Min;
}
int main()
{
    freopen("D:\\in.txt","r",stdin);
    int n;
    scanf("%d",&n);//n个测试用例
    while(n--)
    {
        int m,i,w,x,y,ok=1;
        scanf("%d%d%d",&m,&i,&w);//m个人,谣言发布者i,w个朋友关系
        for(i=0;i<m;i++)//m个人对par[i]赋值i
            par[i]=i;
        while(w--)//w个朋友关系
        {
            scanf("%d%d",&x,&y);
            link(x,y);
        }
        for(i=0;i<m;i++)
            Find(i);
        for(i=0;i<m;i++)
            if(par[i])
            {
                ok=0;
                break;
            }
            if(!ok)
                printf("No\n");
            else
                printf("Yes\n");
    }
    return 0;
}

你可能感兴趣的:(谣言传播)