# hdu Kaka's Matrix Travels（最小费用最大流）

****************************************************************************************************************

  1 #include <stdio.h>
2 #include <stdlib.h>
3 #define M 200001
4 #define maxx 2000
5 #define Max(a, b) a > b ? a : b
6 #define Min(a, b) a < b ? a : b
7 #define inf (1 << 29)
8 struct T
9 {
10     int u, v, val, next, cost;
11 } e[M];
12 int th;
13 int visit[M], pre[M], dis[M], que[M], g[M], pos[M], map[100][100];
14 void add(int u, int v, int val, int cost)
15 {
16     e[th].u = u, e[th].v = v, e[th].val = val, e[th].cost = cost;
17     e[th].next = g[u], g[u] = th++;
18     e[th].u = v, e[th].v = u, e[th].val = 0, e[th].cost = -cost;
19     e[th].next = g[v], g[v] = th++;
20 }
21 int spfa(int s, int t, int n)
22 {
23     int i, u, v, k;
24     for (i = 0; i <= n; i++)
25     {
26         pre[i] = -1, visit[i] = 0;
27     }
29     head = tail = 0;
30     for (i = 0; i <= n; i++) dis[i] = -1;//求最小费用时这里得改成正无穷
31     que[tail++] = s, pre[s] = s, dis[s] = 0, visit[s] = 1;
33     {
35         visit[u] = 0;
36         for (k = g[u]; k != -1; k = e[k].next)
37         {
38             v = e[k].v;
39             if (e[k].val > 0 && dis[u] + e[k].cost > dis[v])//最大费用，求最小费用时这里的改符号
40             {
41                 dis[v] = dis[u] + e[k].cost;
42                 pre[v] = u;
43                 pos[v] = k;
44                 if (!visit[v])
45                 {
46                     visit[v] = 1;
47                     que[tail++] = v;
48                 }
49             }
50         }
51     }
52     if (pre[t] != -1 && dis[t] > -1)//求最小费用时这里改成dit[t] < 正无穷
53     {
54         return 1;
55     }
56     return 0;
57 }
58 int MinCostFlow(int s, int t, int n)
59 {
60     if (s == t)
61     {
62         //这里具体情况具体分析，如果有附加s跟t就不用，如果用数据中的点作为s跟t就得考虑
63         //直接返回某个值。否则spfa里的队列会死循环。
64     }
65     int flow = 0, cost = 0;
66     while (spfa(s, t, n))
67     {
68         int u, min = inf;
69         for (u = t; u != s; u = pre[u])
70         {
71             min = Min(min, e[pos[u]].val);
72         }
73         flow += min;
74         cost += dis[t] * min;
75         for (u = t; u != s; u = pre[u])
76         {
77             e[pos[u]].val -= min;
78             e[pos[u]^1].val += min;
79         }
80     }
81     return cost;
82 }
83 int main()
84 {
85     int n, m, i, j, k, s, t, u, v, cost, ans, x, num, tt;
86     while (scanf("%d%d", &n, &m) - EOF)
87     {
88         for (i = 0, th = 0; i < n * n * 3 + 2; i++)
89         {
90             g[i] = -1;
91         }
92         for (i = 0; i < n; i++)
93         {
94             for (j = 0; j < n; j++)
95             {
96                 scanf("%d", &map[i][j]);
97             }
98         }
99         num = n * n;
100         for (i = 0; i < n; i++)
101         {
102             for (j = 0; j < n; j++)
103             {
104                 x = i * n + j;
105                 add(x, x + num, 1, map[i][j]);
106                 add(x, x + num, inf, 0);
107                 if (i + 1 < n)
108                 {
109                     add(x + num, x + n, inf, 0);
110                 }
111                 if (j + 1 < n)
112                 {
113                     add(x + num, x + 1, inf, 0);
114                 }
115             }
116         }
117         s = 2 * n * n, t = s + 1, n = t + 1;
119         add(s - 1, t, m, 0);
120         ans = MinCostFlow(s, t, t + 1);
121         printf("%d\n", ans);
122     }
123     return 0;
124 }
View Code