• CodeForces


    CF1027D Mouse Hunt

    题目大意:

    (n)个房间,保证每一个房间只会通向另一个房间(a[i]) (可能会通向自己,可能有多个房间通向一个房间)。有一只老鼠会在相通的房间内乱窜。你可以以代价(c[i])放置老鼠夹到任意房间内。求最小代价使得老鼠无论逃窜在哪都会被抓。

    思路:

    模拟样例即可发现,我们可以将图通过(tarjan)缩点变成(DAG)后,统计出度为(0)的强连通分量个数即为要放置的老鼠夹的数量。在每个强连通分量中记录代价最小的花费。

    Code:
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 200010;
    const int INF = 0x3f3f3f3f;
    
    struct Node {
        int to, next;
    } e[N << 1];
    int head[N], tot;
    int dfn[N], low[N], num;
    int co[N], col, minn[N];
    bool vis[N];
    int st[N], top;
    
    int n, c[N], a[N], ans, out[N];
    
    void add_edge(int u, int v) {
        e[++tot].to = v;
        e[tot].next = head[u];
        head[u] = tot;
    }
    
    void tarjan(int u) {
        dfn[u] = low[u] = ++num;
        vis[u] = 1;
        st[++top] = u;
        for (int i = head[u]; ~i; i = e[i].next) {
            int v = e[i].to;
            if (!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            } else if (vis[v]) {
                low[u] = min(low[u], dfn[v]);
            }
        }
        if (low[u] == dfn[u]) {
            co[u] = ++col;
            while (st[top] != u) {
                co[st[top]] = col;
                minn[col] = min(minn[col], c[st[top]]);
                vis[st[top--]] = 0;
            }
            minn[col] = min(minn[col], c[st[top]]);
            vis[st[top--]] = 0;
        }
    }
    
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        memset(head, -1, sizeof(head));
        memset(minn, 0x3f, sizeof(minn));
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> c[i];
        }
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            add_edge(i, a[i]);
        }
        for (int i = 1; i <= n; i++) {
            if (!dfn[i]) tarjan(i);
        }
        for (int i = 1; i <= n; i++) {
            if (co[i] != co[a[i]]) {
                out[co[i]]++;
            }
        }
        for (int i = 1; i <= n; i++) {
            if (!out[co[i]]) {
                ans += minn[co[i]];
                minn[co[i]] = 0;
            }
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    oracle函数 TO_DATE(X[,c2[,c3]])
    oracle函数 TO_CHAR(x[[,c2],C3])
    oracle函数 RAWTOHEX(c1)
    oracle HEXTORAW(c1)
    oracle函数 CONVERT(c1,set1,set2)
    oracle函数 ROWIDTOCHAR(rowid)
    oracle函数 chartorowid(c1)
    创建可按比例调整的布局的 Windows 窗体
    A Byte of Python(简明Python教程) for Python 3.0 下载
    使用异步事件在后台进行计算并报告进度
  • 原文地址:https://www.cnblogs.com/Nepenthe8/p/13956338.html
Copyright © 2020-2023  润新知