zoukankan      html  css  js  c++  java
  • 模板

    https://www.acwing.com/problem/content/369/

    一定要小心缩点之后只剩下一个强连通分量(一个孤立点)的时候,本身就是强连通的了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int MAXN = 1005;
    const int INF = 0x3f3f3f3f;
    
    int n, w[MAXN];
    
    vector<int> G[MAXN], AG[MAXN];
    
    //从i点出发的连通分量,染色为c1[i]
    int c1[MAXN], cntc1;
    
    //i点所在的强连通分量,染色为c2[i]
    int c2[MAXN], cntc2;
    
    //第i个强连通分量内的点
    vector<int> C2[MAXN];
    
    int s[MAXN], cnts;
    
    void dfs1(int u) {
        c1[u] = cntc1;
        for (int v : G[u])
            if (!c1[v])
                dfs1(v);
        s[++cnts] = u;
    }
    
    void dfs2(int u) {
        C2[cntc2].push_back(u);
        c2[u] = cntc2;
        for (int v : AG[u])
            if (!c2[v])
                dfs2(v);
    }
    
    void Kosaraju() {
        //再计算环
        for (int i = 1; i <= n; ++i)
            if (!c1[i]) {
                ++cntc1;
                dfs1(i);
            }
        for (int i = n; i >= 1; --i)
            if (!c2[s[i]]) {
                ++cntc2;
                dfs2(s[i]);
            }
    }
    
    set<int> AG2[MAXN], G2[MAXN];
    int outdeg2[MAXN];
    int indeg2[MAXN];
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        scanf("%d", &n);
    
        for(int i = 1; i <= n; ++i) {
            while(true) {
                int v;
                scanf("%d", &v);
                if(v == 0)
                    break;
                G[i].push_back(v);
                AG[v].push_back(i);
            }
        }
    
        Kosaraju();
    
        /*for(int i = 1; i <= n; ++i) {
            printf("i=%d c2=%d
    ", i, c2[i]);
        }*/
    
        for(int u = 1; u <= cntc2; ++u) {
            for(auto ui : C2[u]) {
                for(auto vi : G[ui]) {
                    if(c2[vi] != u && !G2[u].count(c2[vi])) {
                        ++outdeg2[u];
                        ++indeg2[c2[vi]];
                        G2[u].insert(c2[vi]);
                        AG2[c2[vi]].insert(u);
                    }
                }
            }
        }
    
        int cnt0out = 0, cnt0in = 0;
        for(int i = 1; i <= cntc2; ++i) {
            if(indeg2[i] == 0)
                ++cnt0in;
            if(outdeg2[i] == 0)
                ++cnt0out;
        }
    
        int ans = max(cnt0in, cnt0out);
        if(cntc2 == 1)
            ans = 0;
        printf("%d
    %d
    ", cnt0in, ans);
        return 0;
    }
    
  • 相关阅读:
    Blink示例程序
    arduino入门笔记
    Opentrains 1519 G——最小圆覆盖
    最小圆覆盖入门
    最小球覆盖——模拟退火&&三分套三分套三分
    DAO,Service,Controller各层之间的关系
    史上最全的SpringMVC学习笔记
    pom.xml
    Tomcat入门指南
    tomcat架构
  • 原文地址:https://www.cnblogs.com/Inko/p/11600519.html
Copyright © 2011-2022 走看看