zoukankan      html  css  js  c++  java
  • 「JSOI2014」强连通图

    「JSOI2014」强连通图

    传送门
    第一问很显然就是最大的强连通分量的大小。
    对于第二问,我们先把原图进行缩点,得到 ( ext{DAG}) 后,统计出入度为零的点的个数和出度为零的点的个数,两者取 (max) 就是答案。
    理性证明可以看这里
    参考代码:

    #include <cstdio>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    template < class T > inline T max(T a, T b) { return a > b ? a : b; }
    template < class T > inline T min(T a, T b) { return a < b ? a : b; }
    template < class T > inline void read(T& s) {
        s = 0; int f = 0; char c = getchar();
        while ('0' > c || c > '9') f |= c == '-', c = getchar();
        while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
        s = f ? -s : s;
    }
     
    const int _ = 100005, __ = 2000005;
     
    int tot, head[_]; struct Edge { int ver, nxt; } edge[__];
    inline void Add_edge(int u, int v) { edge[++tot] = (Edge) { v, head[u] }, head[u] = tot; }
     
    int n, m, x[__], y[__];
    int siz[_], idgr[_], odgr[_];
    int col, co[_], num, dfn[_], low[_], top, stk[_];
     
    inline void tarjan(int u) {
        dfn[u] = low[u] = ++num, stk[++top] = u;
        for (rg int i = head[u]; i; i = edge[i].nxt) {
            int v = edge[i].ver;
            if (!dfn[v])
                tarjan(v), low[u] = min(low[u], low[v]);
            else
                if (!co[v]) low[u] = min(low[u], dfn[v]);
        }
        if (low[u] == dfn[u]) { ++col; do ++siz[co[stk[top]] = col]; while (stk[top--] != u); }
    }
     
    int main() {
    #ifndef ONLINE_JUDGE
        file("cpp");
    #endif
        read(n), read(m);
        for (rg int i = 1; i <= m; ++i) read(x[i]), read(y[i]), Add_edge(x[i], y[i]);
        for (rg int i = 1; i <= n; ++i) if (!dfn[i]) tarjan(i);
        for (rg int i = 1; i <= m; ++i) if (co[x[i]] != co[y[i]]) ++odgr[co[x[i]]], ++idgr[co[y[i]]];
        int ans = 0;
        for (rg int i = 1; i <= col; ++i) ans = max(ans, siz[i]);
        printf("%d
    ", ans);
        int icnt = 0, ocnt = 0;
        for (rg int i = 1; i <= col; ++i) icnt += idgr[i] == 0, ocnt += odgr[i] == 0;
        printf("%d
    ", max(icnt, ocnt));
        return 0;
    }
    
  • 相关阅读:
    String类的concat()方法
    字符串转换为时间类型
    translate函数
    弹出窗口
    数据库大小写问题
    360浏览器屏蔽广告
    String.valueOf()
    测试
    选择排序算法
    输出101~200内的质数
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12253738.html
Copyright © 2011-2022 走看看