• UVa 12167 & HDU 2767 强连通分量 Proving Equivalences


    题意:给出一个有向图,问最少添加几条有向边使得原图强连通。

    解法:求出SCC后缩点,统计一下出度为0的点和入度为0的点,二者取最大值就是答案。

    还有个特殊情况就是本身就是强连通的话,答案就是0.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <stack>
     7 using namespace std;
     8 
     9 const int maxn = 20000 + 10;
    10 
    11 int n, m;
    12 
    13 vector<int> G[maxn];
    14 
    15 stack<int> S;
    16 int pre[maxn], low[maxn], sccno[maxn];
    17 int dfs_clock, scc_cnt;
    18 
    19 void dfs(int u, int fa)
    20 {
    21     low[u] = pre[u] = ++dfs_clock;
    22     S.push(u);
    23 
    24     for(int i = 0; i < G[u].size(); i++)
    25     {
    26         int v = G[u][i];
    27         if(!pre[v])
    28         {
    29             dfs(v, u);
    30             low[u] = min(low[u], low[v]);
    31         }
    32         else if(!sccno[v]) low[u] = min(low[u], pre[v]);
    33     }
    34 
    35     if(pre[u] == low[u])
    36     {
    37         scc_cnt++;
    38         for(;;)
    39         {
    40             int x = S.top(); S.pop();
    41             sccno[x] = scc_cnt;
    42             if(x == u) break;
    43         }
    44     }
    45 }
    46 
    47 void find_scc()
    48 {
    49     memset(pre, 0, sizeof(pre));
    50     memset(sccno, 0, sizeof(sccno));
    51     dfs_clock = scc_cnt = 0;
    52     for(int i = 1; i <= n; i++) if(!pre[i]) dfs(i, 0);
    53 }
    54 
    55 int in[maxn], out[maxn];
    56 
    57 int main()
    58 {
    59     int T; scanf("%d", &T);
    60     while(T--)
    61     {
    62         scanf("%d%d", &n, &m);
    63         for(int i = 1; i <= n; i++) G[i].clear();
    64         while(m--)
    65         {
    66             int u, v; scanf("%d%d", &u, &v);
    67             G[u].push_back(v);
    68         }
    69 
    70         find_scc();
    71 
    72         if(scc_cnt == 1) { puts("0"); continue; }
    73 
    74         memset(in, 0, sizeof(in));
    75         memset(out, 0, sizeof(out));
    76         for(int i = 1; i <= n; i++)
    77             for(int j = 0; j < G[i].size(); j++)
    78             {
    79                 int u = sccno[i], v = sccno[G[i][j]];
    80                 if(u != v) { out[u]++; in[v]++; }
    81             }
    82 
    83         int hehe = 0, haha = 0;
    84         for(int i = 1; i <= scc_cnt; i++)
    85         {
    86             if(!in[i]) hehe++;
    87             if(!out[i]) haha++;
    88         }
    89         printf("%d
    ", max(hehe, haha));
    90     }
    91 
    92     return 0;
    93 }
    代码君
  • 相关阅读:
    顧客満足度調査
    GeoStTool.dll过滤图层
    GeoStTool.ini相关技术要点
    GeoStTool.dll与RasterServer通信
    hdu 1007 Quoit Design
    hdu 4325 Flowers
    hdu 2516 取石子游戏
    hdu 1006 Tick and Tick
    CodeForces 101A Homework
    ZOJ Problem Set 1879
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4723701.html
Copyright © 2020-2023  润新知