poj 3422 Kaka's Matrix Travels 费用流

题目链接

给一个n*n的矩阵, 从左上角出发, 走到右下角, 然后在返回左上角,这样算两次。 一共重复k次, 每个格子有值, 问能够取得的最大值是多少, 一个格子的值只能取一次, 取完后变为0。

费用流第一题, 将每个格子拆为两个点, u向u'连一条容量为1, 费用为格子的值的边, u向u'再连一条容量为k-1, 费用为0的边。u'向他右边和下边的格子连一条容量为k, 费用为0的边, 跑一遍费用流就可以。

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <map>
  8 #include <set>
  9 #include <string>
 10 #include <queue>
 11 using namespace std;
 12 #define pb(x) push_back(x)
 13 #define ll long long
 14 #define mk(x, y) make_pair(x, y)
 15 #define lson l, m, rt<<1
 16 #define mem(a) memset(a, 0, sizeof(a))
 17 #define rson m+1, r, rt<<1|1
 18 #define mem1(a) memset(a, -1, sizeof(a))
 19 #define mem2(a) memset(a, 0x3f, sizeof(a))
 20 #define rep(i, a, n) for(int i = a; i<n; i++)
 21 #define ull unsigned long long
 22 typedef pair<int, int> pll;
 23 const double PI = acos(-1.0);
 24 const double eps = 1e-8;
 25 const int mod = 1e9+7;
 26 const int inf = 1061109567;
 27 const int dir[][2] = { {1, 0}, {0, 1}, {0, -1}, {0, 1} };
 28 const int maxn = 2e5+5;
 29 int num, head[maxn*2], s, t, n, k, nn, dis[maxn], flow, cost, cnt, cap[maxn], q[maxn], cur[maxn], vis[maxn];
 30 struct node
 31 {
 32     int to, nextt, c, w;
 33     node(){}
 34     node(int to, int nextt, int c, int w):to(to), nextt(nextt), c(c), w(w) {}
 35 }e[maxn*2];
 36 int spfa() {
 37     int st, ed;
 38     st = ed = 0;
 39     mem2(dis);
 40     ++cnt;
 41     dis[s] = 0;
 42     cap[s] = inf;
 43     cur[s] = -1;
 44     q[ed++] = s;
 45     while(st<ed) {
 46         int u = q[st++];
 47         vis[u] = cnt-1;
 48         for(int i = head[u]; ~i; i = e[i].nextt) {
 49             int v = e[i].to, c = e[i].c, w = e[i].w;
 50             if(c && dis[v]>dis[u]+w) {
 51                 dis[v] = dis[u]+w;
 52                 cap[v] = min(c, cap[u]);
 53                 cur[v] = i;
 54                 if(vis[v] != cnt) {
 55                     vis[v] = cnt;
 56                     q[ed++] = v;
 57                 }
 58             }
 59         }
 60     }
 61     if(dis[t] == inf)
 62         return 0;
 63     cost += dis[t]*cap[t];
 64     flow += cap[t];
 65     for(int i = cur[t]; ~i; i = cur[e[i^1].to]) {
 66         e[i].c -= cap[t];
 67         e[i^1].c += cap[t];
 68     }
 69     return 1;
 70 }
 71 int mcmf() {
 72     flow = cost = 0;
 73     while(spfa())
 74         ;
 75     return cost;
 76 }
 77 void add(int u, int v, int c, int val) {
 78     e[num] = node(v, head[u], c, -val); head[u] = num++;
 79     e[num] = node(u, head[v], 0, val); head[v] = num++;
 80 }
 81 void input() {
 82     int x;
 83     for(int i = 0; i<n; i++) {
 84         for(int j = 0; j<n; j++) {
 85             scanf("%d", &x);
 86             add(i*n+j, i*n+j+nn, 1, x);
 87             add(i*n+j, i*n+j+nn, k-1, 0);
 88         }
 89     }
 90     add(s, 0, k, 0);
 91     add(2*nn-1, t, k, 0);
 92     for(int i = 0; i<n; i++) {
 93         for(int j = 0; j<n; j++) {
 94             for(int k1 = 0; k1<2; k1++) {
 95                 int x = dir[k1][0]+i;
 96                 int y = dir[k1][1]+j;
 97                 if(x>=0&&x<n&&y>=0&&y<n) {
 98                     add(i*n+j+nn, x*n+y, k, 0);
 99                 }
100             }
101         }
102     }
103 }
104 void init() {
105     mem1(head);
106     num = cnt = 0;
107     mem(vis);
108 }
109 int main()
110 {
111     while(~scanf("%d%d", &n, &k)) {
112         init();
113         nn = n*n;
114         s = 2*nn, t = s+1;
115         input();
116         int ans = mcmf();
117         printf("%d\n", -ans);
118     }
119     return 0;
120 }

 

posted on 2015-12-23 12:38  yohaha  阅读(172)  评论(0编辑  收藏  举报

导航