POJ 3422 Kaka's Matrix Travels


题意:有一个N*N的方格,每一个方格里面有一个数字。如今卡卡要从左上角走到右下角,规定每次仅仅能向下或者向右走。每次走到一个格子,将得到该格子的数字,而且该格子的数字变为0。当卡卡走一次时,非常easy求出最大值,问卡卡走k次,可以得到的最大值为多少。

思路:最小费用最大流
关键是怎样构图
1. 将N*N个格点拆分为两个点(i,i + N*N),每一个点之间连一条流量为1,费用为-w的边。再连一条流量为k,费用为0的边。这样就保证了每一个点之间能够走k次。且最多仅仅有一次能拿到费用。
2. 将每一个点与其以下、右边的点连边。流量为k。费用为0.
3. 构造两个源点、汇点。

源点和左上角连边,流量为k,费用为0. 右下角与汇点连边。流量为k,费用为0.


至此,容量网络已经构成。

每次在残余网络中找费用最短路进行增广就可以。


代码:
  1. /*
  2. ID: wuqi9395@126.com
  3. PROG:
  4. LANG: C++
  5. */
  6. #include<map>
  7. #include<set>
  8. #include<queue>
  9. #include<stack>
  10. #include<cmath>
  11. #include<cstdio>
  12. #include<vector>
  13. #include<string>
  14. #include<fstream>
  15. #include<cstring>
  16. #include<ctype.h>
  17. #include<iostream>
  18. #include<algorithm>
  19. using namespace std;
  20. #define INF (1 << 20)
  21. #define LINF (1LL << 60)
  22. #define PI acos(-1.0)
  23. #define mem(a, b) memset(a, b, sizeof(a))
  24. #define rep(i, a, n) for (int i = a; i < n; i++)
  25. #define per(i, a, n) for (int i = n - 1; i >= a; i--)
  26. #define eps 1e-6
  27. #define debug puts("===============")
  28. #define pb push_back
  29. #define mkp make_pair
  30. #define all(x) (x).begin(),(x).end()
  31. #define fi first
  32. #define se second
  33. #define SZ(x) ((int)(x).size())
  34. #define POSIN(x,y) (0 <= (x) && (x) < n && 0 <= (y) && (y) < m)
  35. typedef long long ll;
  36. typedef unsigned long long ULL;
  37. const int maxn = 5555;
  38. const int maxm = 500000;
  39. struct node {
  40. int v, cap, nxt, cost;
  41. } e[maxm * 2];
  42. int g[maxn], cnt, st, ed, n, m;
  43. int ans, flow;
  44. int nt, k;
  45. void add(int u, int v, int cap, int cost) {
  46. e[++cnt].v = v;
  47. e[cnt].cap = cap;
  48. e[cnt].cost = cost;
  49. e[cnt].nxt = g[u];
  50. g[u] = cnt;
  51.  
  52. e[++cnt].v = u;
  53. e[cnt].cap = 0;
  54. e[cnt].cost = -cost;
  55. e[cnt].nxt = g[v];
  56. g[v] = cnt;
  57. }
  58. void init() {
  59. cnt = 1;
  60. ans = flow = 0;
  61. memset(g, 0, sizeof(g));
  62. // 加边
  63. int w;
  64. int p = nt * nt;
  65. for (int i = 1; i <= nt; i++) {
  66. for (int j = 1; j <= nt; j++) {
  67. scanf("%d", &w);
  68. int id = (i - 1) * nt + j;
  69. add(id, id + p, 1, -w);
  70. add(id, id + p, k, 0);
  71. if (i < nt) add(id + p, id + nt, k, 0);
  72. if (j < nt) add(id + p, id + 1, k, 0);
  73. }
  74. }
  75. st = 0, ed = p * 2 + 1;
  76. n = ed;
  77. add(st, 1, k, 0);
  78. add(p * 2, ed, k, 0);
  79. }
  80.  
  81. int dis[maxn], que[maxn], pre[maxn];
  82. bool vis[maxn];
  83. bool spfa() {
  84. int font = 0, rear = 1;
  85. for(int i = 0; i <= n; i ++) {
  86. dis[i] = INF;
  87. vis[i] = false;
  88. }
  89. dis[st] = 0;
  90. que[0] = st;
  91. vis[st] = true;
  92. while(rear != font) {
  93. int u = que[font++];
  94. font %= n;
  95. vis[u] = false;
  96. for(int i = g[u]; i; i = e[i].nxt) {
  97. int v = e[i].v;
  98. if(e[i].cap && dis[v] > dis[u] + e[i].cost) {
  99. dis[v] = dis[u] + e[i].cost;
  100. pre[v] = i;
  101. if(!vis[v]) {
  102. vis[v] = true;
  103. que[rear++] = v;
  104. rear %= n;
  105. }
  106. }
  107. }
  108. }
  109. if(dis[ed] == INF) return false;
  110. return true;
  111. }
  112. void augment() {
  113. int u, p, mi = INF;
  114. for(u = ed; u != st; u = e[p ^ 1].v) {
  115. p = pre[u];
  116. mi = min(mi, e[p].cap);
  117. }
  118. for(u = ed; u != st; u = e[p ^ 1].v) {
  119. p = pre[u];
  120. e[p].cap -= mi;
  121. e[p ^ 1].cap += mi;
  122. ans += mi * e[p].cost; // cost记录的为单位流量费用。必须得乘以流量。
  123. }
  124. flow += mi;
  125. }
  126. int MCMF() {
  127. init();
  128. while(spfa()) augment();
  129. return ans;
  130. }
  131. int main () {
  132. while(~scanf("%d%d", &nt, &k)) {
  133. printf("%d\n", -MCMF());
  134. }
  135. return 0;
  136. }

POJ 3422 Kaka&#39;s Matrix Travels (最小费用最大流)的更多相关文章

  1. POJ 3422 Kaka&#39;s Matrix Travels(费用流)

    POJ 3422 Kaka's Matrix Travels 题目链接 题意:一个矩阵.从左上角往右下角走k趟,每次走过数字就变成0,而且获得这个数字,要求走完之后,所获得数字之和最大 思路:有点类似 ...

  2. POJ训练计划3422_Kaka&#39;s Matrix Travels(网络流/费用流)

    解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次仅仅能向右和向下走,走到一个格子上加上格子的数,能够走k次.问最大的和是多少. 思路: 建图:每一个格子掰成两个点,分别叫" ...

  3. [poj] 3422 Kaka's Matrix Travels || 最小费用最大流

    原题 给一个N*N的方阵,从[1,1]到[n,n]走K次,走过每个方格加上上面的数,然后这个格上面的数变为0.求可取得的最大的值. 要求最大值,所以把边权全为负跑最小费用即可.因为只有第一次经过该点的 ...

  4. POJ 2135 Farm Tour (网络流,最小费用最大流)

    POJ 2135 Farm Tour (网络流,最小费用最大流) Description When FJ's friends visit him on the farm, he likes to sh ...

  5. poj3422 Kaka's Matrix Travels(最小费用最大流问题)

    /* poj3422 Kaka's Matrix Travels 不知道 k次 dp做为什么不对??? 看了大牛的代码,才知道还可以这样做! 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序 ...

  6. POJ3422 Kaka&#39;s Matrix Travels 【最大费用最大流】

    Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8006   Accepted:  ...

  7. POJ 3686:The Windy's(最小费用最大流)***

    http://poj.org/problem?id=3686 题意:给出n个玩具和m个工厂,每个工厂加工每个玩具有一个时间,问要加工完这n个玩具最少需要等待的平均时间.例如加工1号玩具时间为t1,加工 ...

  8. poj Kaka&#39;s Matrix Travels

    Kaka's Matrix Travels 题目: 给出一个矩阵.求仅仅能向下或者向右的情况下能得到的最大和.一般的是指遍历一次,而这个是能够反复走K次.每经过一次后就把该点设为0.求最大和. 算法: ...

  9. POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

    题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...

随机推荐

  1. Flex 全屏显示方法

    1,修改html-template下的index.template.html文件…增加四行 1</html> 上述文件增加了四行…见我文中有提示 2,Mxml文件: 假如一个button按 ...

  2. POJ 2762 Going from u to v or from v to u? (Tarjan) - from lanshui_Yang

    Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has ...

  3. [置顶] JDK-Future 模式和实现

    最近的项目用到了多线程,发现java.util.concurrent.Future蛮好用的. 像平时,写多线程一般使用Thread/Runnable,直接扔给线程池执行就好了.但是遇到了一些需要获取线 ...

  4. paip.最新的c++ qt5.1.1环境搭建跟hello world

    paip.最新的c++ qt5.1.1环境搭建跟hello world 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://bl ...

  5. 悬浮二维码 QQ ToTop

    //回顶部 <div id="lqdbe" style="position: absolute; visibility: visible; z-index: 1;  ...

  6. git 无法添加文件夹下文件

    最近做项目时,发现无法提交某个子文件夹下的文件. google后发现可能是该子文件夹下有.git文件夹导致无法上传. 删除子文件夹下.git后,依然无法提交子文件夹下的文件. 继续google, 尝试 ...

  7. jquery日历签到控件的实现

    calendar.js var calUtil = { //当前日历显示的年份 showYear:2015, //当前日历显示的月份 showMonth:1, //当前日历显示的天数 showDays ...

  8. 门面(Facade)模式--医院,保安系统实例

    门面(Facade)模式 http://www.cnblogs.com/zhenyulu/articles/55992.html

  9. 2015-12-27 socket的用法

    sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) sk.bind(address) s.bind(address) 将套接字绑定到地址.a ...

  10. JS 移动动画

    function moveElement(elementId, final_x, final_y,interval) {            if (!document.getElementById ...