【费用流】codevs1227 方格取数 2
2015-02-04 21:58
267 查看
1227 方格取数 2
时间限制: 1 s空间限制: 128000 KB
题目等级 : 大师 Master
题解
题目描述 Description
给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大输入描述 Input Description
第一行两个数n,k(1<=n<=50, 0<=k<=10)接下来n行,每行n个数,分别表示矩阵的每个格子的数
输出描述 Output Description
一个数,为最大和样例输入 Sample Input
3 11 2 3
0 2 1
1 4 2
样例输出 Sample Output
11数据范围及提示 Data Size & Hint
1<=n<=50, 0<=k<=10= =拖了半年写出来的题 纪念一下(……) 代码还是基本参考的姜神的(…………)
基本裸的拆点网络流 0 0。。。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int inf = 0x3f3f3f; int N, K; int map[55][55]; int head[105*105*2]; int k = 0; int S, T; int ans = 0; struct ed { int u, v, w, flow, next; }e[105*105*5]; inline int in(int i, int j) { return (((i-1) * N + j) << 1) - 1; } inline int out(int i, int j) { return ((i-1) * N + j) << 1; } inline void adde(int u, int v, int f, int w) { e[k] = (ed){u, v, w, f, head[u]}; head[u] = k++; e[k] = (ed){v, u, -w, 0, head[v]}; head[v] = k++; } inline void build_map() { memset(head, -1, sizeof(head)); for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { int In = in(i, j); int Out = out(i, j); adde(In, Out, 1, map[i][j]); adde(In, Out, inf, 0); if(i < N) adde(Out, in(i+1, j), inf, 0); if(j < N) adde(Out, in(i, j+1), inf, 0); } } S = 0; T = out(N, N) + 1; adde(S, in(1, 1), K, 0); adde(out(N, N), T, K, 0); } int dis[105*105*2]; int vis[105*105*2]; int per[105*105*2]; queue <int> q; bool spfa() { memset(dis, -inf, sizeof(dis)); memset(vis, 0, sizeof(vis)); dis[S] = 0; q.push(S); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; if(e[i].flow && dis[v] < dis[u] + e[i].w) { per[v] = i; dis[v] = dis[u] + e[i].w; if(!vis[v]) { vis[v] = 1; q.push(v); } } } } return dis[T] > 0; } int main() { cin >> N >> K; for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { scanf("%d", &map[i][j]); } } build_map(); while(spfa()) { int f = inf; for(int i = T; i != S; i = e[per[i] ^ 1].v) { f = min(f, e[per[i]].flow); } for(int i = T; i != S; i = e[per[i] ^ 1].v) { e[per[i]].flow -= f; e[per[i] ^ 1].flow += f; } ans += f * dis[T]; } cout << ans << endl; return 0; }
相关文章推荐
- Codevs 1227方格取数 (费用流
- 【费用流】【CODEVS】1227 方格取数2
- Codevs 1227 方格取数 2(费用流)
- codevs 1227 方格取数 2 【网络流+费用流基础】
- codevs1227 方格取数2 注意数组啊啊啊啊啊啊啊啊啊啊
- codevs1227 方格取数2
- code vs 1227 方格取数 2
- codevs 1227 方格取数 2
- 【Codevs1907】方格取数3(最小割)
- 【codevs1033】蚯蚓的游戏问题,费用流
- 二维费用背包codevs1669运输装备
- Codevs_P1227 方格取数2(拆点网络流+最小费用流)
- codevs 1169 传纸条 && 1043 方格取数(棋盘DP)
- CodeVS1907 方格取数3
- Codevs 1043 ==洛谷 P1004 方格取数
- Codevs : 1033 蚯蚓的游戏问题 (费用流
- 【codevs1043】 方格取数
- codevs 1907 方格取数 网络流
- CODE[VS] 1033 蚯蚓的游戏问题(最大费用最大流?)
- CODEVS 1907 方格取数 3