首页 > 其他 > 详细

Luogu P2057 [SHOI2007]善意的投票

时间:2019-03-28 16:42:42      阅读:122      评论:0      收藏:0      [点我收藏+]

题目链接 \(Click\) \(Here\)

考虑模型转换。变成文理分科二选一带收益模型,就一波带走了。

如果没有见过这个模型的话,这里讲的很详细。

#include <bits/stdc++.h>
using namespace std;

#define LL long long
const int N = 400010;
const int M = 800010;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f3f3f3f3f3f3f;

int n, m, cnt = -1, head[N];

struct edge {
    int nxt, to; LL f;
}e[M];

void add_len (int u, int v, LL f) {
    e[++cnt] = (edge) {head[u], v, f}; head[u] = cnt;
    e[++cnt] = (edge) {head[v], u, 0}; head[v] = cnt;
}

int node (int x) {return x;}
int f1 (int x) {return n + m * 0 + x;}
int f2 (int x) {return n + m * 1 + x;} 

queue <int> q;
int cur[N], deep[N];

bool bfs (int s, int t) {
    memcpy (cur, head, sizeof (head));
    memset (deep, 0x3f, sizeof (deep));
    deep[s] = 0; q.push (s);
    while (!q.empty ()) {
        int u = q.front (); q.pop ();
        for (int i = head[u]; ~i; i = e[i].nxt) {
            int v = e[i].to;
            if (deep[v] == INF && e[i].f) {
                deep[v] = deep[u] + 1;
                q.push (v);
            }
        }
    }
    return deep[t] != INF;
}

LL dfs (int u, int t, LL lim) {
    if (u == t || !lim) {
        return lim;
    }
    int tmp = 0, flow = 0;
    for (int &i = cur[u]; ~i; i = e[i].nxt) {
        int v = e[i].to;
        if (deep[v] == deep[u] + 1) {
            tmp = dfs (v, t, min (lim, e[i].f));
            lim -= tmp;
            flow += tmp;
            e[i ^ 0].f -= tmp;
            e[i ^ 1].f += tmp;
            if (!lim) break;
        }
    }
    return flow;
}

int main () {
    memset (head, -1, sizeof (head));
    cin >> n >> m;
    int s = f2 (m + 1), t = f2 (m + 2); 
    for (int i = 1; i <= n; ++i) {
        static int cho;
        cin >> cho;
        if (cho == 0) {
            add_len (s, node (i), INF + 1);
            add_len (node (i), t, INF + 0);
        } else {
            add_len (s, node (i), INF + 0);
            add_len (node (i), t, INF + 1);
        }
        //s -> 0, t -> 1
    }
    for (int i = 1; i <= m; ++i) {
        static int x, y;
        cin >> x >> y;
        add_len (s, f1 (i), 1); add_len (f1 (i), node (x), INFF); add_len (f1 (i), node (y), INFF);
        add_len (f2 (i), t, 1); add_len (node (x), f2 (i), INFF); add_len (node (y), f2 (i), INFF);
    }
    LL min_cut = 0;
    while (bfs (s, t)) {
        min_cut += dfs (s, t, INFF);
    }
    LL ans = (min_cut - n * INF - m);
    cout << ans << endl;
}  

Luogu P2057 [SHOI2007]善意的投票

原文:https://www.cnblogs.com/maomao9173/p/10615758.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!