wikioi 传话

一个朋友网络,如果a认识b,那么如果a第一次收到某个消息,那么会把这个消息传给b,以及所有a认识的人。

如果a认识bb不一定认识a

所有人从1n编号,给出所有“认识”关系,问如果i发布一条新消息,那么会不会经过若干次传话后,这个消息传回给了i1<=i<=n

第一行是nm,表示人数和认识关系数。

接下来的m行,每行两个数ab,表示a认识b1<=a, b<=n。认识关系可能会重复给出,但一行的两个数不会相同。

一共n行,每行一个字符TF。第i行如果是T,表示i发出一条新消息会传回给i;如果是F,表示i发出一条新消息不会传回给i

4 6

1 2

2 3

4 1

3 1

1 3

2 3

T

T

T

F

n<=1000。m<=10000

1<=a, b<=n

题解

拓扑排序,dfs判环。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,head[1002],t;
struct bian
{int to,nx;} e[10002];
bool v[1002],h[1002];
void dfs(int x)
{
	if(h[t]) return;
    v[x]=1;
    if(x==t) {h[t]=1;return;}
    int i=head[x];
	while(i)
	   {if(!v[e[i].to]) dfs(e[i].to);//防止重复循环 
	    i=e[i].nx;
	   }
}
void doit()
{
	 for(t=1;t<=n;t++)
        {memset(v,0,sizeof(v));
         int i=head[t];
		 while(i) {dfs(e[i].to); i=e[i].nx;}
        } 
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
       {int x,y;
		scanf("%d%d",&x,&y);
        e[i].to=y; e[i].nx=head[x]; head[x]=i;
       }
    doit();
    for(int i=1;i<=n;i++)
       {if(h[i]) printf("T\n");
        else printf("F\n");
	   }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值