CODEVS 1506 传话 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CODEVS 1506 传话 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:http://codevs.cn/problem/1506/

题目描述 Description

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

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

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

输入描述 Input Description

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

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

 

输出描述 Output Description

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

 

样例输入 Sample Input

4 6

1 2

2 3

4 1

3 1

1 3

2 3

样例输出 Sample Output

T

T

T

F

数据范围及提示 Data Size & Hint

n<=1000

1<=a, b<=n

 

分析:

Floyd传递闭包。

G[i][j]表示j能收到i发出的消息。把认识的关系用Floyd不断地传递下去,最后如果G[i][i]=1就说明i能收到自己发出的消息。

这题数据比较弱,n^3居然没有TLE_(:з」∠)_数据范围再大可能就要写Tarjan了

 

AC代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 
 6 inline void read(int &x)
 7 {
 8     char ch = getchar(),c = ch;x = 0;
 9     while(ch < 0 || ch > 9) c = ch,ch = getchar();
10     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
11     if(c == -) x = -x;
12 }
13 
14 int n,m,a,b,flag;
15 int G[1001][1001];
16 
17 void Floyd()
18 {
19     for(int k = 1;k <= n;++ k)
20         for(int i = 1;i <= n;++ i)
21             for(int j = 1;j <= n;++ j)
22                 if(G[i][k] && G[k][j])
23                     G[i][j] = 1;
24 }
25 
26 int main()
27 {
28     read(n),read(m);
29     for(int i = 1;i <= m;++ i)
30     {
31         read(a),read(b);
32         G[a][b] = 1;
33     }
34     Floyd();
35     for(int i = 1;i <= n;++ i)
36     {
37         if(G[i][i] == 1)
38             printf("T\n");
39         else
40             printf("F\n");
41     }
42     return 0;
43 }

 

 

以上是关于CODEVS 1506 传话 题解的主要内容,如果未能解决你的问题,请参考以下文章

codevs1506传话

161110 小測

1506 传话 (暴力DFS或者Tarjan模板题)

codevs 5964 [SDOI2017]序列计数

CODEVS 1214 线段覆盖 题解

CODEVS 1048 石子归并 题解