zoukankan      html  css  js  c++  java
  • Strongly connected HDU

    题面

    传送门

    题解

    正难则反, 求多少条边不能建

    首先完全连通图总边数 n * (n - 1)

    减去给出的 m 条边

    缩点之后, scc可以互连, 添加边, 使得最后留下一个 出度为1为, 入度为1 的连个 scc就可

    即留下一个入度为1的scc, 其他scc建边完全联通, or 留下一个scc出度为1, 其他scc建边完全联通

    int n, m, _, k;
    vector<VI> h;
    int c[N], scnt, st[N], top;
    int dfn[N], df, low[N];
    bool inst[N];
    
    void tarjan(int x) {
        dfn[x] = low[x] = ++df, inst[st[++top] = x] = 1;
        for (auto &y : h[x]) {
            if (!dfn[y]) { tarjan(y); umin(low[x], low[y]); }
            else if (inst[y]) umin(low[x], dfn[y]);
        }
        if (low[x] == dfn[x]) {
            ++scnt; int y;
            do { inst[y = st[top--]] = 0; c[y] = scnt; } while (x != y);
        }
    }
    
    int main() {
        IOS; int cas = 0;
        for (cin >> _; _; --_) {
            cin >> n >> m; vector<VI>(n + 1).swap(h);
            cout << "Case " << ++cas << ": ";
            rep (i, 1, m) {
                int u, v; cin >> u >> v;
                h[u].pb(v);
            }
            memset(dfn, 0, sizeof dfn); df = scnt = 0;
            rep (i, 1, n) if (!dfn[i]) tarjan(i);
            if (scnt == 1) { cout << "-1
    "; continue; }
            VI cnt(scnt + 1); vector<bool> in(scnt + 1), out(scnt + 1);
            rep (i, 1, n) ++cnt[c[i]];
            rep (i, 1, n) for (auto &y : h[i]) if (c[i] != c[y]) in[c[y]] = out[c[i]] = 1;
            int ans = 1e9;
            rep (i, 1, scnt) if (!in[i] || !out[i]) umin(ans, cnt[i]);
            cout << (ll)n * (n - 1) - m - (ll)ans * (n - ans) << '
    ';
        }
        return 0;
    }
    
  • 相关阅读:
    flask强大的第三方组件之falsk-sqlalchemy
    flask 外键关系和多对多查询
    flask sqlalchemy 单表查询
    functools模块
    面试题
    ansible git
    python 操作 表格
    matplotlib
    node,npm,webpack,vue-cli模块化编程安装流程
    Webpack
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14113574.html
Copyright © 2011-2022 走看看