zoukankan      html  css  js  c++  java
  • poj~1236 Network of Schools 强连通入门题

    一些学校连接到计算机网络。这些学校之间已经达成了协议:

    每所学校都有一份分发软件的学校名单(“接收学校”)。

    请注意,如果B在学校A的分发名单中,则A不一定出现在学校B的名单中
    您需要编写一个计划,计算必须接收新软件副本的最少学校数量,

    以便软件根据协议(子任务A)到达网络中的所有学校。作为进一步的任务,

    我们希望确保通过将新软件的副本发送到任意学校,该软件将覆盖网络中的所有学校。

    为了实现这一目标,我们可能需要扩大新成员的接收者名单。

    计算必须做的扩展的最小数目,以便我们发送新软件的任何学校,

    它将到达所有其他学校(Subtask B)。

    一种扩展意味着将一名新成员引入一所学校的接收者名单。

    这题强连通水题 ,模板题目,

    第一问求出最少要几个点才能到任意点

    其实就是一个强连通缩点后,求出有几个入度为0的点,

    第二问求出要加上几条边把所点后的有向无环图变成一个强连通图

    就是求 max(sumin, sumout)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <string>
     4 #include <algorithm>
     5 #include <queue>
     6 using namespace std;
     7 
     8 const int maxn = 1e5 + 10;
     9 int n, m, u, v, tot, top, cnt, flag;
    10 struct node {
    11     int v, next;
    12 } edge[maxn];
    13 int head[maxn], instack[maxn], s[maxn];
    14 int dfn[maxn], low[maxn], belong[maxn];
    15 void init() {
    16     tot = cnt = top = flag = 0;
    17     memset(s, 0, sizeof(s));
    18     memset(head, -1, sizeof(head));
    19     memset(dfn, 0, sizeof(dfn));
    20     memset(instack, 0, sizeof(instack));
    21 }
    22 void add(int u, int v) {
    23     edge[tot].v = v;
    24     edge[tot].next = head[u];
    25     head[u] = tot++;
    26 }
    27 void tarjin(int v) {
    28     dfn[v] = low[v] = ++flag;
    29     instack[v] = 1;
    30     s[top++] = v;
    31     for (int i = head[v] ; i != -1 ; i = edge[i].next) {
    32         int j = edge[i].v;
    33         if (!dfn[j]) {
    34             tarjin(j);
    35             low[v] = min(low[v], low[j]);
    36         } else if (instack[j]) low[v] = min(low[v], dfn[j]);
    37     }
    38     if (dfn[v] == low[v]) {
    39         cnt++;
    40         int t;
    41         do {
    42             t = s[--top];
    43             instack[t] = 0;
    44             belong[t] = cnt;
    45         } while(t != v) ;
    46     }
    47 }
    48 void solve() {
    49     for (int i = 1 ; i <= n ; i++)
    50         if (!dfn[i]) tarjin(i);
    51 }
    52 int in[maxn], out[maxn];
    53 int main() {
    54     while(scanf("%d", &n) != EOF) {
    55         init();
    56         memset(in, 0, sizeof(in));
    57         memset(out, 0, sizeof(out)) ;
    58         for (int i = 1 ; i <= n ; i++) {
    59             int v;
    60             scanf("%d", &v);
    61             while(v) {
    62                 add(i, v);
    63                 scanf("%d", &v);
    64             }
    65         }
    66         for (int i = 1  ; i <= n ; i++)
    67             if (!dfn[i]) tarjin(i);
    68         for (int i = 1 ; i <= n ; i++) {
    69             for (int j = head[i] ; ~j ; j = edge[j].next) {
    70                 if (belong[edge[j].v] != belong[i]) {
    71                     in[belong[edge[j].v]]++;
    72                     out[belong[i]]++;
    73                 }
    74             }
    75         }
    76         int sumin = 0, sumout = 0;
    77         for (int i = 1 ; i <= cnt ; i++) {
    78             if (!in[i]) sumin++;
    79             if (!out[i])sumout++;
    80         }
    81         printf("%d
    ", sumin);
    82         if (cnt == 1) printf("0
    ");
    83         else printf("%d
    ", max(sumin, sumout));
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    【题解】魔术棋子
    NHOI2019小结
    【题解】滑雪
    【题解】最大平台
    【题解】洪水
    【题解】N皇后问题
    【题解】四色定理
    使用Docker快速搭建Jenkins
    使用Docker快速搭建Gitlab
    测试用Docker Swarm环境搭建
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/9073147.html
Copyright © 2011-2022 走看看