将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0(保证可以多次通过该点,但费用只计算一次)。

  另外伪点B与原点右侧与下方的点有一条单向路(邻接表实现需要建立反向空边),残留容量为+∞,费用为0。源点0到点1有一条单向路,残留容量为K(可以通过K次),最后一个点的伪点2*n*n与汇点2*n*n+1有一条单向边,残留容量为K,两条边的费用都为0。

  构图成功后,走一次最小费用最大流即可。

  1. //最小费用最大流问题-拆点
  2. //Time:47Ms Memory:624K
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdio>
  6. #include<algorithm>
  7. #include<queue>
  8. using namespace std;
  9. #define MAX 55
  10. #define MAXN 5005
  11. #define INF 0x3f3f3f3f
  12. struct Edge{
  13. int u,v,r,w,next;
  14. Edge(){}
  15. Edge(int U,int V,int R,int W,int N):u(U),v(V),r(R),w(W),next(N){}
  16. }e[MAXN*8];
  17. int n,k;
  18. int s,t;
  19. int h[MAXN],le;
  20. int m[MAX][MAX];
  21. int pre[MAXN];
  22. int cost[MAXN];
  23. bool vis[MAXN];
  24. void add(int u,int v,int r,int w)
  25. {
  26. e[le] = Edge(u,v,r,w,h[u]); h[u] = le++;
  27. e[le] = Edge(v,u,0,-w,h[v]); h[v] = le++;
  28. }
  29. void build()
  30. {
  31. add(s, 1, k, 0);
  32. add(2*n*n, t, k, 0);
  33. for(int i = 1; i <= n*n; i++)
  34. {
  35. add(i, n*n+i, 1, -m[(i - 1)/n + 1][(i - 1)%n + 1]);
  36. add(i, n*n+i, k, 0);
  37. if(i % n) add(i+n*n, i+1, INF, 0);
  38. if(i <= n*(n-1)) add(i+n*n, i+n, INF, 0);
  39. }
  40. }
  41. bool spfa()
  42. {
  43. memset(pre,-1,sizeof(pre));
  44. memset(vis,false,sizeof(vis));
  45. memset(cost,INF,sizeof(cost));
  46. queue<int> q;
  47. q.push(s);
  48. cost[s] = 0; vis[s] = true;
  49. while(!q.empty()){
  50. int cur = q.front();
  51. q.pop(); vis[cur] = false;
  52. for(int i = h[cur]; i != -1; i = e[i].next)
  53. {
  54. int v = e[i].v;
  55. if(e[i].r && cost[v] > cost[cur] + e[i].w){
  56. cost[v] = cost[cur] + e[i].w;
  57. pre[v] = i;
  58. if(!vis[v]){
  59. vis[v] = true; q.push(v);
  60. }
  61. }
  62. }
  63. }
  64. return cost[t] == INF? false: true;
  65. }
  66. int maxcostflow()
  67. {
  68. int maxFlow = 0;
  69. while(spfa()){ //增广路
  70. int mind = INF;
  71. for(int i = pre[t]; i != -1; i = pre[e[i].u])
  72. mind = min(mind, e[i].r);
  73. for(int i = pre[t]; i != -1; i = pre[e[i].u])
  74. {
  75. e[i].r -= mind;
  76. e[i^1].r += mind;
  77. }
  78. maxFlow += mind*cost[t];
  79. }
  80. return maxFlow;
  81. }
  82. int main()
  83. {
  84. //freopen("in.txt", "r", stdin);
  85. memset(h, -1, sizeof(h));
  86. scanf("%d%d", &n,&k);
  87. s = 0; t = 2*n*n+1;
  88. for(int i = 1; i <= n; i++)
  89. for(int j = 1; j <= n; j++)
  90. scanf("%d", &m[i][j]);
  91. build();
  92. printf("%d\n", -maxcostflow());
  93. return 0;
  94. }

ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)的更多相关文章

  1. 最小费用最大流——EK+SPFA

    终于把最小费用最大流学会了啊-- 各种奇奇怪怪的解释我已经看多了,但在某些大佬的指点下,我终于会了. 原来是个好水的东西. 最小费用最大流是什么? 不可能不知道网络流吧?如果不知道,自行百度去-- 费 ...

  2. 2018牛客网暑期ACM多校训练营(第五场) E - room - [最小费用最大流模板题]

    题目链接:https://www.nowcoder.com/acm/contest/143/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...

  3. 51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1084 1084 矩阵取数问题 V2  基准时间限制:2 秒 空 ...

  4. POJ 3422 Kaka's Matrix Travels 【最小费用最大流】

    题意: 卡卡有一个矩阵,从左上角走到右下角,卡卡每次只能向右或者向下.矩阵里边都是不超过1000的正整数,卡卡走过的元素会变成0,问卡卡可以走k次,问卡卡最多能积累多少和. 思路: 最小费用最大流的题 ...

  5. hdu 2686 Matrix 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...

  6. hdu 1533 Going Home 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 On a grid map there are n little men and n house ...

  7. HDU 5988.Coding Contest 最小费用最大流

    Coding Contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  8. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

  9. UVa11082 Matrix Decompressing(最小费用最大流)

    题目大概有一个n*m的矩阵,已知各行所有数的和的前缀和和各列所有数的和的前缀和,且矩阵各个数都在1到20的范围内,求该矩阵的一个可能的情况. POJ2396的弱化版本吧..建图的关键在于: 把行.列看 ...

随机推荐

  1. Switch&NAT 测试

    测试环境: PC1:Windows10 iperf3 PC2:Ubuntu iperf3 都装有千兆网卡,直连的iperf速度是935Mbps. 因为TXRX两个方向的数据是差不多的,下面的测试数据只 ...

  2. AutoHotKey实现将站点添加到IE的Intranet本地站点

    最近在内部推行CRM系统,其中的CPQ组件要求必须将站点加入到"本地Intranet”才可以正常使用,但是由于使用用户比较多(超过几千人),并且每个用户的计算机水平都不一样,所以让用户手工去 ...

  3. SQLite剖析之动态内存分配

    SQLite通过动态内存分配来获取各种对象(例如数据库连接和SQL预处理语句)所需内存.建立数据库文件的内存Cache.保存查询结果. 1.特性    SQLite内核和它的内存分配子系统提供以下特性 ...

  4. 基于FPGA的飞机的小游戏

    基于FPGA的飞机的小游戏 实验原理 该实验主要分为4个模块,采用至上而下的设计方法进行设计.由50M的晶振电路提供时钟源,VGA显示控制模块.图形显示控制模块.移动模块的时钟为25M,由时钟分频电路 ...

  5. Android BLE 蓝牙编程(一)

    最近在研究这个,等我有时间来写吧! 终于在端午节给自己放个假,现在就来说说关于android蓝牙ble的 最近的学习成果吧!! 需要材料(写个简单教程吧--关于小米手环的哦!嘿嘿) Android 手 ...

  6. jQuery1.9之后使用on()绑定 动态生成元素的 事件无效

    来自互联网: 需要绑定a的父级元素(此元素必须为静态元素,不是后来动态生成的),然后设定on()方法的selector参数才行: $('p').on('mouseenter', 'a', functi ...

  7. jquery版楼层滚动特效

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>楼 ...

  8. ajax 多个表单值问题,表单序列化加其它表单值

    $.ajax({ type: "post", url: "{:u('cart/totalByCard')}?t="+Math.random(9999), dat ...

  9. hdu3530 单调队列

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  10. DB&SQL备忘

    DB2最佳分页语句 SELECT * FROM ( SELECT inner2_.*, ROWNUMBER() OVER(ORDER BY ORDER OF inner2_) AS rownumber ...