• Luogu P2057 [SHOI2007]善意的投票


    题目链接 (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;
    }  
    
  • 相关阅读:
    [HNOI2004]L语言
    [TJOI2018]异或
    如何定位低效SQL?
    索引失效的情况有哪些?
    trace的作用?
    show profile的作用?
    索引的使用原则
    MySQL主从复制的步骤
    什么是聚簇索引
    什么是全文索引?
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10615758.html
Copyright © 2020-2023  润新知