• 解题笔记——NIT 遥远的村庄


    某个小镇有 N 个村庄,村庄编号1-N,给出 M 条单向道路,不存在环,即不存在 村庄A可以到达村庄B 且 村庄B也可以到达村庄A的情况。
    如果村庄A与村庄B之间存在一条单向道路,则说村庄A和村庄B之间存在联系,联系具有无向性,即如果村庄A和村庄B有联系,则村庄B和村庄A有联系;联系具有传递性,即如果存在村庄A和村庄B有联系,村庄B和村庄C有联系,则村庄A和村庄C有联系。
    现在小镇要在某些村庄里建垃圾站,对建垃圾站的村庄要满足与之有联系的村庄都可以通过单向道路到达该村庄。问小镇能建多少个垃圾站。

     

    Input

    输入包含多组数据,对于每组数据:
    第一行输入N,M,数据范围1<=n<=1000,0<=m<10000。
    接下来M行,每行两个整数,s,t,代表 s 可以到达 t 。

     

    Output

    对于每组数据,输出一个整数代表答案。

     

    Sample Input

    10 6
    1 2
    2 3
    3 4
    6 7
    7 8
    9 10

    Sample Output

    4

    Hint

    案例中有10个村庄,道路情况如下:

    1->2->3->4

    5

    6->7->8

    9->10

    村庄4可以建垃圾站,因为与之有联系的村庄都能到达他;同理村庄5,村庄8,村庄10,所以答案有4个。

    解题思路:

    要建垃圾站的话,该村庄所在的关于村庄联系的联通块内的结点数和他的单向道路能到达的结点数相同,但是建边要反向建,本来u到v的边要建成v到u的边,用并查集算各个联通块内结点数,然后dfs算能到达多少个结点再跟该联通块内结点总数比较,相等的话说明可以建垃圾站

    难点在看不懂题意

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef unsigned long long ull;
     5 #define INF 0x3f3f3f3f
     6 const ll MAXN = 1e3 + 7;
     7 const ll MAXM = 1e4 + 7;
     8 const ll MOD = 1e9 + 7;
     9 const double pi = acos(-1);
    10 int n, m;
    11 int vis[MAXN];
    12 int pre[MAXN];
    13 vector<int> V[MAXN];
    14 int root[MAXN]; //根结点的位置记录联通块内结点数
    15 int cnt;
    16 void init()
    17 {
    18     memset(vis, 0, sizeof(vis));
    19     memset(root, 0, sizeof(root));
    20     for (int i = 1; i <= n; i++)
    21         pre[i] = i, V[i].clear();
    22 }
    23 int find(int x) //查找根结点
    24 {
    25     int r = x;
    26     while (r != pre[r]) //寻找根结点
    27         r = pre[r];
    28     int i = x, j;
    29     while (pre[i] != r) //路径压缩
    30     {
    31         j = pre[i];
    32         pre[i] = r;
    33         i = j;
    34     }
    35     return r;
    36 } //并查集求联通块块数
    37 //遍历有向图结点
    38 void DFS(int u)
    39 {
    40     cnt++;
    41     vis[u] = 1;
    42     for (int i = 0; i < V[u].size(); i++)
    43     {
    44         int v = V[u][i];
    45         if (!vis[v])
    46         { //如果该节点未被访问,则深度遍历
    47             DFS(v);
    48         }
    49     }
    50 }
    51 int main()
    52 {
    53     while (~scanf("%d%d", &n, &m))
    54     {
    55         init();
    56         int ans = 0;
    57         for (int i = 0; i < m; i++)
    58         {
    59             int u, v;
    60             scanf("%d%d", &u, &v);
    61             V[v].push_back(u);
    62             int fa = find(u);
    63             int fb = find(v);
    64             if (fa != fb)
    65                 pre[fa] = fb;
    66         }
    67         for (int i = 1; i <= n; i++)
    68             root[find(i)]++;
    69         for (int i = 1; i <= n; i++)
    70         {
    71             memset(vis, 0, sizeof(vis));
    72             cnt = 0;
    73             DFS(i);
    74             if (cnt == root[find(i)])
    75                 ans++;
    76         }
    77         printf("%d
    ", ans);
    78     }
    79     return 0;
    80 }
    81 /* 14 7
    82 1 8
    83 2 8
    84 4 5
    85 7 8
    86 9 7
    87 6 7
    88  6 8
    89 */

     

  • 相关阅读:
    【性能测试】二、TPS、QPS、RT和吞吐量这些都是什么?
    【性能测试】一、哪那么多概念,不就是这一条吗?
    【测试基础】九、如何做 API 测试?异步的呢?
    【测试基础】八、创建测试数据的时机
    【测试基础】七、你如何准备测试数据?
    【测试基础】六、做好测试计划需要注意这些
    【测试基础】五、这样提bug单,开发小哥还会怼你么?
    【测试基础】四、你的测试覆盖率是多少?
    【测试基础】三、为什么要做自动化测试?哪种项目合适?
    【测试基础】二、我好像真的不会设计“好的”测试用例
  • 原文地址:https://www.cnblogs.com/graytido/p/10846632.html
Copyright © 2020-2023  润新知