[bzoj3876][AHOI2014]支线剧情——上下界费用流
2017-02-21 11:42
441 查看
题目
题解
建立s和t,然后s向1连下限0上限inf费用0的边,除1外所有节点向t连下限0上限inf费用0的边,对于每条边下限为1上限为inf费用为经过费用,然后我们只有做上下界网络流构出新图,跑最小费用可行流即可。
至于建立新图,我是这样建立的(如图)
另外推荐一篇文章:Menci的博客
代码
#include <bits/stdc++.h> using namespace std; #define ll long long const int inf = INT_MAX; const int maxn = 305 * 4; const int M = 10000; struct edge1 { int from; int to; int low; int high; int cost; }; vector<edge1> es; struct edge { int from; int to; int cap; int cost; }; vector<edge> edges; vector<int> G[maxn]; inline void add_edge(int from, int to, int cap, int cost) { edges.push_back((edge){from, to, cap, cost}); edges.push_back((edge){to, from, 0, -cost}); int m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } inline int read() { char c = getchar(); int f = 1, x = 0; while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); } while (isdigit(c)) x = x * 10 + c - '0', c = getchar(); return x * f; } int n, s, t, V; void build_network() { for (int i = 0; i < es.size(); i++) { edge1 &e = es[i]; add_edge(e.from, e.to, e.high - e.low, e.cost); add_edge(e.from, e.to, e.low, e.cost - M); } } int dist[maxn], a[maxn], pree[maxn], inq[maxn]; bool spfa(int s, int t, int &cost) { for (int i = 0; i < V; i++) dist[i] = inf; memset(pree, 0, sizeof(pree)); memset(inq, 0, sizeof(inq)); a[s] = inf; dist[s] = 0; queue<int> q; q.push(s); inq[s] = 1; while (!q.empty()) { int u = q.front(); q.pop(); inq[u] = 0; for (int i = 0; i < G[u].size(); i++) { edge &e = edges[G[u][i]]; if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) { pree[e.to] = G[u][i]; dist[e.to] = dist[u] + e.cost; a[e.to] = min(e.cap, a[u]); if (!inq[e.to]) { q.push(e.to); inq[e.to] = 1; } } } } if (dist[t] >= inf) return false; cost += a[t] * dist[t]; int u = t; while (u != s) { edges[pree[u]].cap -= a[t]; edges[pree[u] ^ 1].cap += a[t]; u = edges[pree[u]].from; } return true; } int mcmf(int s, int t) { int cost = 0; while (spfa(s, t, cost)) ; // cout << "Hey:" << cost << endl; return cost; } int main() { // freopen("input", "r", stdin); scanf("%d", &n); s = 0, t = n + 1, V = t + 1; int cnt = 0; es.push_back((edge1){s, 1, 0, inf, 0}); for (int i = 1; i <= n; i++) { int k; k = read(); for (int j = 0; j < k; j++) { int a, b; a = read(); b = read(); es.push_back((edge1){i, a, 1, inf, b}); cnt += 1; } es.push_back((edge1){i, t, 0, inf, 0}); } build_network(); int ans = mcmf(s, t); printf("%d", ans + M * cnt); }
相关文章推荐
- 【BZOJ3876】[Ahoi2014]支线剧情 有上下界费用流
- BZOJ 3876([Ahoi2014]支线剧情-带下界的最小费用可行流)
- BZOJ 3876: [Ahoi2014]支线剧情【下界费用流
- 【bzoj3876】【AHOI2014】【支线剧情】【有上下界的费用流】
- 【bzoj3876】[Ahoi2014]支线剧情 有上下界费用流
- BZOJ 3876: [Ahoi2014]支线剧情 [上下界费用流]
- 【bzoj3876】[Ahoi2014]支线剧情 有上下界的费用流
- 有下界的最小费用可行流2.0(bzoj 3876: [Ahoi2014]支线剧情)
- BZOJ 3876: [Ahoi2014]支线剧情(有源有汇有下界的费用流)
- 【有上下界网络流+费用流多路增广】【bzoj 3876】: [Ahoi2014]支线剧情
- bzoj 3876: [Ahoi2014]支线剧情 (有上下界的费用流)
- bzoj3876[AHOI2014]支线剧情(有上下界的费用流)
- BZOJ 3876: [Ahoi2014]支线剧情 带下界的费用流
- [BZOJ3876][Ahoi2014]支线剧情(有源汇有上下界的费用流)
- [bzoj3876][AHOI2014]支线剧情 有下界费用流
- [上下界费用流] BZOJ 3876 [Ahoi2014]支线剧情
- 【有源汇上下界费用流】BZOJ 3876 [Ahoi2014]支线剧情
- [BZOJ 3876][Ahoi2014]支线剧情:上下界网络流
- [上下界有源汇最小费用可行流] BZOJ 3876: [Ahoi2014&Jsoi2014]支线剧情
- BZOJ 3876 AHOI 2014 支线剧情 有上下界的费用流