标签:ref line def efi div oid map bfs http
原题连接 : http://poj.org/problem?id=1149
题目大意:有m个养猪场,n个顾客,每个顾客都有若干把养猪场的钥匙,最开始养猪场是全部锁上的,每个顾客来的时候可以用钥匙打开固定的养猪场并进行购买,每个顾客都有一个购买上限;
购买完后可以把打开的猪场里的猪任意的调整到别的打开的猪场;求购买数最大是多少;
解题思路:有一个源点s和汇点t,然后把所有的养猪场的第一个顾客与s连一条边,边权位这些养猪场的总猪数;将每个养猪场的后续顾客和前一个顾客连边权值为无穷;
将所有顾客和t连边,权值为这个顾客的购买上限;跑一遍最大流算法;
ac代码 :
#include <iostream> #include <string> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <functional> #include <map> #include <set> #include <stack> #define FT(a, b) memset(a, b, sizeof(a)) #define FAT(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; const int M = 2e4 + 100; const int N = 1e2 + 100; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int n, m, k; int h[N], e[M], ne[M], w[M], idx; int deepth[N], gap[N]; int pig[N * 10]; int s = 0, t = 1; int min_cost, max_flow; void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } void f_add(int a, int b, int c) { add(a, b, c), add(b, a, 0); } void bfs() { FT(deepth, -1); FAT(gap); queue<int> q; q.push(t); deepth[t] = 0; gap[deepth[t]]++; while (q.size()) { int a = q.front(); q.pop(); for (int i = h[a]; ~i; i = ne[i]) { int j = e[i]; if (deepth[j] == -1) { deepth[j] = deepth[a] + 1; gap[deepth[j]]++; q.push(j); } } } } int dfs(int now, int flow) { if (now == t) return flow; int nowflow = 0; for (int i = h[now]; ~i; i = ne[i]) { int j = e[i]; if (w[i] && deepth[j] == deepth[now] - 1) { int k = dfs(j, min(flow - nowflow, w[i])); w[i] -= k, w[i ^ 1] += k, nowflow += k; if (flow == nowflow) return nowflow; } } --gap[deepth[now]]; if (!gap[deepth[now]]) gap[s] = n + 2; ++deepth[now]; ++gap[deepth[now]]; return nowflow; } int ISAP() { int ans = 0; bfs(); while (gap[s] < n) ans += dfs(s, INF); return ans; } vector<int> v[N * 10]; int main() { #ifdef ONLINE_JUDGE #else freopen("/home/wjy/code/in.txt", "r", stdin); #endif ios::sync_with_stdio(0); cin.tie(0); int T = 1; // scanf("%d", &T); while (T--) { idx = 0; FT(h, -1); cin >> m >> n; s = 0, t = n + 1; for (int i = 1; i <= m; i++) cin >> pig[i]; for (int i = 1; i <= n; i++) { int a, b, k; cin >> a; int val = 0; while (a--) { int key; cin >> key; if (v[key].empty()) val += pig[key]; v[key].push_back(i); } cin >> b; if (val) f_add(s, i, val); f_add(i, t, b); } for (int i = 1; i <= m; i++) { for (int j = 1; j < v[i].size(); j++) { f_add(v[i][j - 1], v[i][j], INF); } } printf("%d\n", ISAP()); } return 0; }
标签:ref line def efi div oid map bfs http
原文地址:https://www.cnblogs.com/ignorance/p/13181875.html