bzoj1391 [Ceoi2008]order
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1391
【题解】
简单最小割建模。
加当前弧优化!!!
# include <queue> # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 3e6 + 10, N = 2510; const int mod = 1e9+7; # define RG register # define ST static int n, m, S, T; int cur[N], head[N], nxt[M], to[M], tot=1, flow[M]; inline void add(int u, int v, int fl) { ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; flow[tot] = fl; } inline void adde(int u, int v, int fl) { add(u, v, fl), add(v, u, 0); } namespace MF { queue<int> q; int c[N]; inline bool bfs() { while(!q.empty()) q.pop(); for (int i=1; i<=T; ++i) c[i] = -1; c[S] = 1; q.push(S); while(!q.empty()) { int top = q.front(); q.pop(); for (int i=head[top]; i; i=nxt[i]) { if(flow[i] == 0 || c[to[i]] != -1) continue; c[to[i]] = c[top] + 1; q.push(to[i]); if(to[i] == T) return 1; } } return 0; } inline int dfs(int x, int low) { if(x == T) return low; int r = low, fl; for (int i=cur[x]; i; i=nxt[i]) { if(flow[i] == 0 || c[to[i]] != c[x] + 1) continue; fl = dfs(to[i], min(r, flow[i])); flow[i] -= fl; if(flow[i] > 0) cur[x] = i; flow[i^1] += fl; r -= fl; if(!r) return low; } if(low==r) c[x]=-1; return low-r; } inline int main() { int ret = 0; while(bfs()) { for (int i=1; i<=n+m+2; ++i) cur[i] = head[i]; ret += dfs(S, 1e9); } return ret; } } int main() { int ans = 0; cin >> n >> m; S = n+m+1; T = n+m+2; for (int i=1, P, pn, t; i<=n; ++i) { scanf("%d%d", &P, &pn); ans += P; adde(S, i, P); while(pn--) { scanf("%d%d", &t, &P); adde(i, t+n, P); } } for (int i=1, P; i<=m; ++i) { scanf("%d", &P); adde(i+n, T, P); } cout << ans - MF::main(); return 0; }