zoukankan      html  css  js  c++  java
  • HDU 3836 Equivalent Sets(强连通分量,有向图改强连通图)

    题目链接

    题目大意

      给一个图问最少添加多少边之后它会变成强连通图。

    解题思路

      对于一个缩点之后的dag图,我们考虑它的入度为0的点和出度为0的点。我们把一个入度为0的和出度为0的点相连,或者把一个入度为0的点连到另外一个度数大于等于2的点上,又或者把一个出度为0的点连到另外一个度数大于等于2的点上,都能构成一个新的连通分量,那么很明显,需要添加的最少的边就是入度为0的点与出度为0的点两者中的最大值。但是有一个特殊情况需要考虑,如果缩点之后只剩一个点,那么说明这个图本身就已经是一个强连通图了,那么就不需要添加边了。

    代码

    const int maxn = 2e5+10;
    vector<int> e[maxn];
    int n, m;
    int dfn[maxn], low[maxn], dn;
    int scc[maxn], sc, sk[maxn], tp; 
    int in[maxn], out[maxn];
    void tarjan(int u) {
        dfn[u] = low[u] = ++dn;
        sk[++tp] = u;
        for (auto v : e[u]) {
            if (!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if (!scc[v]) low[u] = min(low[u], dfn[v]);
        }
        if (dfn[u]==low[u]) {
            ++sc;
            while(true) {
                int v = sk[tp--];
                scc[v] = sc;
                if (u==v) break; 
            }
        }
    }
    int main() {
        while(~scanf("%d%d", &n, &m)) {
            dn = sc = tp = 0;
            zero(dfn); zero(low); zero(scc); zero(in); zero(out); zero(sk);
            for (int i = 0; i<=n; ++i) e[i].clear();
            for (int i = 0, u, v; i<m; ++i) {
                scanf("%d%d", &u, &v);
                e[u].push_back(v);
            }
            int cnt = 0;
            for (int i = 1; i<=n; ++i)
                if (!dfn[i]) tarjan(i);
            for (int i = 1; i<=n; ++i) 
                for (auto v : e[i])
                    if (scc[i]!=scc[v]) {
                        ++out[scc[i]];
                        ++in[scc[v]];
                    }
            int maxi = 0, maxo = 0;
            for (int i = 1; i<=sc; ++i) {
                if (!in[i]) ++maxi;
                if (!out[i]) ++maxo;
            }
            if (sc==1) printf("0
    ");
            else printf("%d
    ", max(maxi,maxo));
        }
        return 0;
    }
    
  • 相关阅读:
    Windbg 基本调试常识(转)
    善用VS中的Code Snippet来提高开发效率
    如何跟踪调试Software product?
    Visual Studio 2008 每日提示(二十七)
    6步确保 windbg 成功调试 .net(转)
    Visual Studio 2005 重置设置
    Print to Output /To trace runtime
    Windbg安装和配置(转)
    C++与C#交互
    All hands on deck
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12881655.html
Copyright © 2011-2022 走看看