hdu Kaka's Matrix Travels(最小费用最大流)
把题意写一下: 给你一个n*n的矩阵,每个格子都有一个非负整数,从左上角走到右下角,收集走过的数字,累加,但是只能向右或者向下走,走过之后数字就变为0,让你求从左上角到右下角,走k次之后,所得的最大值是多少。
典型的最小费用最大流入门题,只需在建图时,把源点到1的cap设成k,对走完一次变成0的处理时,只需拆点,拆成两条边,一条容量为1,权值为点权,另一条是跳板,容量为inf,费用为0,即可
****************************************************************************************************************
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 } 28 int head, tail; 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; 32 while (head != tail) 33 { 34 int u = que[head++]; 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; 118 add(s, 0, m, 0); 119 add(s - 1, t, m, 0); 120 ans = MinCostFlow(s, t, t + 1); 121 printf("%d\n", ans); 122 } 123 return 0; 124 }