• [CF1082G]Petya and Graph


    题目大意:一张无向图$G=(V,E)$,定义$f(G)=sumlimits_{ein E}w_e-sumlimits_{vin V}w_v$,给一张$n(nleqslant10^3)$个点$m(mleqslant10^3)$条边的无向图,求$max_{G'in G}{f(G')}$。

    题解:最大权闭合子图。

    源点往有代价物品连其边权为其代价的边。

    有代价物品往选了它可能产生收益的组连边权为的边。

    每个组往汇点连边权为其收益的边。

    由源点向原图中的每条边连一条容量为其收益的边,原图中的边向它的两个端点连容量为$infty$的边,原图中的每个点向汇点连容量为其代价的边

    把总收益减去最小割即可

    卡点:

    C++ Code:

    #include <algorithm>
    #include <cstdio>
    #define maxn 1010
    #define maxm 1010
    const int N = maxn + maxm, M = N + 2 * maxm;
    const int inf = 0x3f3f3f3f;
    
    namespace Network_Flow {
    	int lst[N], head[N], cnt = 1;
    	struct Edge {
    		int to, nxt, w;
    	} e[M << 1];
    	inline void addedge(int a, int b, int c) {
    		e[++cnt] = (Edge) { b, head[a], c }; head[a] = cnt;
    		e[++cnt] = (Edge) { a, head[b], 0 }; head[b] = cnt;
    	}
    
    	long long MF;
    	int n, st, ed;
    	int GAP[N], d[N];
    	int q[N], h, t;
    
    	void init() {
    		GAP[d[ed] = 1] = 1;
    		for (int i = 0; i < n; ++i) lst[i] = head[i];
    		q[h = t = 0] = ed;
    		while (h <= t) {
    			int u = q[h++];
    			for (int i = head[u]; i; i = e[i].nxt) {
    				int v = e[i].to;
    				if (!d[v]) {
    					d[v] = d[u] + 1;
    					++GAP[d[v]];
    					q[++t] = v;
    				}
    			}
    		}
    	}
    	int dfs(int u, int low) {
    		if (!low || u == ed) return low;
    		int w, res = 0;
    		for (int &i = lst[u]; i; i = e[i].nxt) if (e[i].w) {
    			int v = e[i].to;
    			if (d[u] == d[v] + 1) {
    				w = dfs(v, std::min(low, e[i].w));
    				res += w, low -= w;
    				e[i].w -= w, e[i ^ 1].w += w;
    				if (!low) return res;
    			}
    		}
    		if (!(--GAP[d[u]])) d[st] = n + 1;
    		++GAP[++d[u]], lst[u] = head[u];
    		return res;
    	}
    	void ISAP(int S, int T) {
    		st = S, ed = T;
    		init();
    		while (d[st] <= n) MF += dfs(st, inf);
    	}
    }
    using Network_Flow::addedge;
    
    int n, m;
    long long sum;
    int main() {
    	scanf("%d%d", &n, &m); Network_Flow::n = n + m + 2;
    	int st = 0, ed = n + m + 1;
    	for (int i = 1, x; i <= n; ++i) {
    		scanf("%d", &x);
    		addedge(st, i, x);
    	}
    	for (int i = 1, a, b, c; i <= m; ++i) {
    		scanf("%d%d%d", &a, &b, &c);
    		addedge(a, n + i, inf);
    		addedge(b, n + i, inf);
    		addedge(n + i, ed, c);
    		sum += c;
    	}
    	Network_Flow::ISAP(st, ed);
    	printf("%lld
    ", sum - Network_Flow::MF);
    	return 0;
    }
    

      

  • 相关阅读:
    iOS开发JSON文件解析数据成Model的过程简单介绍
    ios 开发中 --做登陆注册时编译出现的错误和解决方法
    iOS 开发 SMSSDK-免费短信获取的实现方法
    IOS 设计 面试题及答案
    Cycle (KMP + hash)
    ATM Mechine (概率DP)
    Bubble Sort (找规律)
    The All-purpose Zero (最长公共子序列)
    Substring (后缀数组 + 计数)
    Lucky 7 (容斥原理 + 中国剩余定理)
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10341430.html
Copyright © 2020-2023  润新知