zoukankan      html  css  js  c++  java
  • P4177 [CEOI2008]order 网络流,最小割,最大权闭合子图

    题目链接 (Click) (Here)

    如果没有租用机器就是一个裸的最大权闭合子图。现在有了租用机器应该怎么办呢?

    单独拆点是不行的,因为会和直接买下的情况脱离关系,租借是和连边直接相关的,那么就可以考虑在边上下功夫。我们把从工程到机器的连边从(INF)变成租用费用,这样再跑最大权闭合子图,就可以同时考虑租用费用了。如果租用费用过高就会割断(选用)购买机器的费用,反之亦然。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 2410;
    const int M = 4000010;
    const int INF = 0x3f3f3f3f;
    
    struct Graph {
    	int cnt, head[N];
    
    	struct edge {
    		int nxt, to, f;
    	}e[M];
    
    	void Init () {
    		cnt = -1;
    		memset (head, -1, sizeof (head));
    	}
    
    	void add_len (int u, int v, int f) {
    		e[++cnt] = (edge) {head[u], v, f}; head[u] = cnt;
    		e[++cnt] = (edge) {head[v], u, 0}; head[v] = cnt;
    	}
    
    	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;
    	}
    
    	int dfs (int u, int t, int 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 Dinic (int s, int t) {
    		int min_cut = 0;
    		while (bfs (s, t)) {
    			min_cut += dfs (s, t, INF);
    		}
    		return min_cut;
    	}
    }G;
    
    int n, m;
    
    int A (int x) {return n * 0 + x;}
    int B (int x) {return n * 1 + x;}
    
    int main () {
    	//freopen ("data.in", "r", stdin);
    	cin >> n >> m; G.Init ();
    	int s = N - 1, t = N - 2, ans = 0;
    	for (int i = 1; i <= n; ++i) {
    		static int w, k, p, r;
    		cin >> w >> k; ans += w;
    		G.add_len (s, A (i), w); //get_val = w
    		for (int j = 1; j <= k; ++j) {
    			cin >> p >> r;
    			G.add_len (A (i), B (p), r); //rent cost = r
    		}
    	}
    	for (int i = 1; i <= m; ++i) {
    		static int w; cin >> w;
    		G.add_len (B (i), t, w);
    	}
    	cout << ans - G.Dinic (s, t) << endl;
    }
    
    
  • 相关阅读:
    MSSQL '20210806'转换成'2021-08-06'
    cxgrid 列内容居中显示
    CXGRID 导出EXCEL
    study PostgreSQL【3-get数据库中all表以及表的字段信息】
    study PostgreSQL【2-FireDAC连接PostgreSQL】
    高格-销售发票勾稽销售出货的赠品处理【14】
    study PostgreSQL【1-PostgreSQL对象】
    高格-负库存导致系统异常的处理【13】
    study Rust-9【组织管理】
    基础资料属性不符合目标组织要求:物料.允许库存,物料.来料检验
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10693416.html
Copyright © 2011-2022 走看看