[codevs 1033] 蚯蚓的游戏问题
2015-01-18 11:01
246 查看
[codevs 1033] 蚯蚓的游戏问题
题解:
首先每个点只能走一次,所以要靠拆点 (X -> Xi, Xj) 来限制每个点走的次数,容量为1,费用为食物量的相反数。从源点向所有第一层的点 Xi 连一条容量为1,费用为0的边。
从最后一层的点 Xj 向汇点连一条容量为1,费用为0的边。
因为从源点向所有第一层的点连边不考虑蚯蚓个数,即没有限制最大流量,所以再建立一个超级汇点,从汇点到超级汇点连一条容量为蚯蚓条数,费用为0的边,求最小费用最大流,最后答案就是从源点到超级汇点的费用的相反数;也可以建立超级源点,从超级源点向源点连边限制流量。
代码:
耗时:19ms内存:872B
#include<cstdio> #include<iostream> #include<vector> #include<queue> #include<algorithm> using namespace std; const int maxn = 3000 + 10; const int INF = 1000000007; int n, m, k, s, t, delta; int map[maxn][maxn], ID[maxn][maxn]; struct Edge { int from, to, cap, flow, cost; }; vector<Edge> edges; vector<int> G[maxn]; void AddEdge(int from, int to, int cap, int cost) { edges.push_back((Edge){from, to, cap, 0, cost}); edges.push_back((Edge){to, from, 0, 0, -cost}); int sz = edges.size(); G[from].push_back(sz-2); G[to].push_back(sz-1); } bool inq[maxn]; int a[maxn], d[maxn], p[maxn]; bool BellmanFord(int& flow, int& cost) { for(int i = s; i <= t; i++) d[i] = INF; memset(inq, 0, sizeof(inq)); d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF; queue<int> Q; Q.push(s); while(!Q.empty()) { int x = Q.front(); Q.pop(); inq[x] = 0; for(int i = 0; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(e.cap > e.flow && d[e.to] > d[x] + e.cost) { d[e.to] = d[x] + e.cost; p[e.to] = G[x][i]; a[e.to] = min(a[x], e.cap-e.flow); if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; } } } } if(d[t] == INF) return 0; flow += a[t]; cost += d[t] * a[t]; int x = t; while(x != s) { edges[p[x]].flow += a[t]; edges[p[x]^1].flow -= a[t]; x = edges[p[x]].from; } return 1; } void MincostMaxflow() { int flow = 0, cost = 0; while(BellmanFord(flow, cost)); cout << -cost << endl; } void init() { cin >> n >> m >> k; for(int i = 1; i <= n; i++) for(int j = 1; j < m+i; j++) { ID[i][j] = ++t; cin >> map[i][j]; } delta = t; t = t * 2 + 2; int _t = t-1; for(int x = 1; x <= n; x++) for(int y = 1; y < x+m; y++) { int& id = ID[x][y]; AddEdge(id, id+delta, 1, -map[x][y]); if(x == 1) AddEdge(s, id, 2, 0); if(x == n) AddEdge(id+delta, _t, 2, 0); //key1 else { AddEdge(id+delta, ID[x+1][y], 1, 0); AddEdge(id+delta, ID[x+1][y+1], 1, 0); } } AddEdge(_t, t, k, 0); } int main() { init(); MincostMaxflow(); return 0; }
相关文章推荐
- 【CODEVS】1033 蚯蚓的游戏问题
- [codevs 1033] 蚯蚓的游戏问题
- CODEVS 1033 蚯蚓的游戏问题
- CODE[VS]1033 蚯蚓的游戏问题
- 蚯蚓的游戏问题 wikioi 1033
- codevs 1033 蚯蚓的游戏问题 费用流+拆点
- CODE[VS] 1033 蚯蚓的游戏问题(最大费用最大流?)
- 【wikioi1033】蚯蚓的游戏问题
- 【codevs1033】 蚯蚓的游戏问题
- codevs 1033 蚯蚓的游戏问题----费用流
- 1033 蚯蚓的游戏问题
- 【wikioi】1033 蚯蚓的游戏问题(费用流)
- 【codevs1033】蚯蚓的游戏问题
- wikioi1033 蚯蚓的游戏问题
- 【CODEVS1033】蚯蚓的游戏问题(费用流)
- codevs1033 蚯蚓的游戏问题
- 【codevs1033】蚯蚓的游戏问题,费用流
- codevs1033 蚯蚓的游戏问题 裸最小费用最大流,注意要拆点
- Codevs : 1033 蚯蚓的游戏问题 (费用流
- CODEVS_1033 蚯蚓的游戏问题 网络流 最小费用流 拆点