• 2007 Simulation message


    题目

    问题描述:

    兴趣小组的同学来自各个学校,为了增加友谊,晚会上又进行了一个传话游戏,如果a认识b,那么a收到某个消息,就会把这个消息传给b,以及所有a认识的人。

    如果a认识b,b不一定认识a。

    所有人从1到n编号,给出所有’认识’关系,问如果i发布一条新消息,那么会不会经过若干次传话后,这个消息传回给了i(1in)。

    输入格式:

    第一行是两个数n(n<1,000)和m(m<10,000),两数之间有一个空格,表示人数和认识关系数。

    接下来的m行,每行两个数a和b,表示a认识b。(1a,bn)。认识关系可能会重复给出,但一行的两个数不会相同。

    输出格式:

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

    样例输入输出:

    message.in

    4 6

    1 2

    2 3

    4 1

    3 1

    1 3

    2 3

    message.out

    T

    T

    T

    F

    分析

    这道题明显就是要找一个关系环,也就是找一个人到另一个人最后回到最初那个人的环。找环显然用拓扑。这道题当中用了一个小技巧,我们用了两次相对的循环,一次针对入度,一次针对出度,然后没有vis标记过的就是在环上的点。(很聪明的办法)为什么会用到这样双向的拓扑,是因为如果只按照入度来做,就有可能有被包围在环当中的点被忽略了,所以从出度的角度由内向外再扫一遍保证答案正确。

    注意数据大小!别乱开数组大小!当主程序return一个很大的值的时候注意检查数组大小!

    程序

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN = 1005;
     4 int n, m, u, v, dg[MAXN], og[MAXN];
     5 vector<int> a[1005],b[1005];
     6 bool g[MAXN][MAXN], vis[MAXN];
     7 queue<int> S;
     8 int main()
     9 {
    10     freopen("message.in","r",stdin);
    11     freopen("message.out","w",stdout);
    12     cin >> n >> m;
    13     for (int i = 1; i <= m; i++)
    14     {
    15         scanf("%d%d",&u,&v);
    16         if (!g[u][v])
    17         {
    18             dg[v]++, og[u]++;
    19             g[u][v] = true;
    20             a[u].push_back(v);
    21             b[v].push_back(u);
    22         }
    23     }
    24     for (int i = 1; i <= n; i++)
    25         if (!dg[i])
    26             S.push(i);
    27     while (!S.empty())
    28     {
    29         int temp = S.front();
    30         S.pop();
    31         vis[temp] = true;
    32         for (int i = 0; i < a[temp].size(); i++)
    33         {
    34             dg[a[temp][i]]--;
    35             if (!dg[a[temp][i]])
    36                 S.push(a[temp][i]);
    37         }
    38     }
    39     for (int i = 1; i <= n; i++)
    40         if (!og[i])
    41             S.push(i);
    42     while (!S.empty())
    43     {
    44         int temp = S.front();
    45         S.pop();
    46         vis[temp] = true;
    47         for (int i = 0; i < b[temp].size(); i++)
    48         {
    49             og[b[temp][i]]--;
    50             if (!og[b[temp][i]])
    51                 S.push(b[temp][i]);
    52         }
    53     }
    54     for (int i = 1; i <= n; i++)
    55         if (!vis[i])
    56             printf("T
    ");
    57         else
    58             printf("F
    ");
    59     return 0;
    60 }
  • 相关阅读:
    深度优先搜索和广度优先搜索的比较与分析
    BFS() DFS() 模板
    jQuery EasyUI1.2.4发布了
    深入理解dispatcher和redirect的区别
    分享一份jquery easyui的培训文档
    生活中的十悟
    CSS Hack的基本原理
    推荐11款jQuery开发的复选框和单选框美化插件
    NodeJS初探之三——新星的力量
    由浅到深的分析Javascript OO之写类方式之一:构造函数
  • 原文地址:https://www.cnblogs.com/OIerPrime/p/9325687.html
Copyright © 2020-2023  润新知