zoukankan      html  css  js  c++  java
  • 间谍网络

    洛谷题目链接
    loj题目链接

    tarjan求强联通分量,每个强联通分量内的间谍可以互相揭发,缩点

    跑拓扑排序,每个间谍(强连通分量)只可能被拓扑排序比他小的揭发

    扫一遍,没被控制的收买一下,收买不了输出no.(代码实现的时候有些区别,这样也是对的)

    #include <bits/stdc++.h>
    using namespace std;
    int low[5000], color[5000], cnt = 0, w[5000], uu[50000], vv[50000], cover[5000], rd[5000], line[5000], lc = 0,
                                 ww[5000], colornum = 0, dfn[5000], t = 0, sta[5000], stac = 0,
                                in[5000], head[5000];
    struct node {
        int to, nxt;
    } road[10000];
    void build(int u, int v) 
    {
        road[++cnt].to = v;
        road[cnt].nxt = head[u];
        head[u] = cnt;
    }
    void tarjan(int u) 
    {
        low[u] = dfn[u] = ++t;
        in[u] = 1, sta[++stac] = u;
        for (int i = head[u]; i; i = road[i].nxt) 
    	{
            int v = road[i].to;
            if (!dfn[v]) 
    		{
                tarjan(v);
                low[u] = min(low[u], low[v]);
            } else if (in[v])
                low[u] = min(low[u], dfn[v]);
        }
        if (dfn[u] == low[u]) 
    	{
            color[u] = ++colornum, in[u] = 0;
            if (w[u] != -1)
                ww[colornum] = w[u];
            while (sta[stac] != u) 
    		{
                in[sta[stac]] = 0;
                if (w[sta[stac]] != -1) 
    			{
                    if (ww[colornum] == -1)
                        ww[colornum] = w[sta[stac]];  // QAQ
                    else
                        ww[colornum] = min(ww[colornum], w[sta[stac]]);
                }
                color[sta[stac]] = colornum;
                stac--;
            }
            stac--;
        }
    }
    int ans = 0;
    void tuopu(int u) {
        line[++lc] = u;
        for (int i = head[u]; i; i = road[i].nxt) {
            int v = road[i].to;
            rd[v]--;
            if (!rd[v])
                tuopu(v);
        }
    }
    void dfs(int u) {
        cover[u] = 1;
        for (int i = head[u]; i; i = road[i].nxt) {
            int v = road[i].to;
            if (!cover[v])
                dfs(v);
        }
    }
    int main() {
        memset(w, -1, sizeof(w));
        memset(ww, -1, sizeof(ww));
        int n, p, r, u, v, ans = 0;
        cin >> n >> p;
        for (int i = 1; i <= p; i++) {
            int x;
            cin >> x;
            cin >> w[x];
        }
        cin >> r;
        for (int i = 1; i <= r; i++) {
            cin >> uu[i] >> vv[i];
            build(uu[i], vv[i]);
        }
        for (int i = 1; i <= n; i++) {
            if (!dfn[i]) {
                tarjan(i);
            }
        }
        memset(head, 0, sizeof(head));
        cnt = 0;
        for (int i = 1; i <= r; i++) {
            if (color[uu[i]] != color[vv[i]]) {
                build(color[uu[i]], color[vv[i]]);
                rd[color[vv[i]]]++;
            }
        }
        for (int i = 1; i <= colornum; i++) {
            if (!rd[i])
                tuopu(i);
        }
        for (int i = 1; i <= lc; i++) {
            if (!cover[line[i]] && ww[line[i]] != -1) {
                ans += ww[line[i]];
                dfs(line[i]);
            } 
        }
        int f = 0;
        for (int i = 1; i <= n; i++) //直接循环强联通分量 不能保证编号最小 
    	// 循环的顺序是按编号从小到大,但是实际最先成为强联通分量,可能是编号较大的某个儿子
    	{
            if (!cover[color[i]]) {
                f = 1;
                cout << "NO"<<"
    "<< i;
                break;  // QAQ
            }
        }
        if (f == 0)
            cout << "YES"
                 << "
    "
                 << ans;
        return 0;
    }
    
  • 相关阅读:
    581. 最短无序连续子数组
    217. 存在重复元素
    189. 旋转数组
    169. 多数元素
    122. 买卖股票的最佳时机 II
    119. 杨辉三角 II
    118. 杨辉三角
    外显子分析思路总结(Exome Sequencing Analysis review)
    宁夏采样记20181129
    haploview出现“results file must contain a snp column”的解决方法
  • 原文地址:https://www.cnblogs.com/qwq-/p/13632636.html
Copyright © 2011-2022 走看看