1 /*
  2 poj3422 Kaka's Matrix Travels
  3 不知道 k次 dp做为什么不对???
  4 看了大牛的代码,才知道还可以这样做!
  5 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序一直陷入死循环,真心花了好长时间,快崩溃了。无语.....
  6 题意:有个方阵,每个格子里都有一个非负数,从左上角走到右下角,每次走一步,只能往右或往下走,经过的数字拿走
  7 每次都找可以拿到数字和最大的路径走,走k次,求最大和
  8
  9 这是 最大费用最大流 问题  每次spfa都找的是一条和最大的路径 s--到左上角的边流量是K限制增广次数
 10
 11 求最大费用最大流只需要把费用换成相反数,用最小费用最大流求解即可
 12
 13
 14 构图过程:
 15 每个点拆分成两个  a   a'   之间建两条边(当然还要建退边),分别是   (费用为该点相反数,流量为1) (费用为0,流量为k-1)
 16 路过这点时,可以通过前边那条边拿到数字,
 17 以后再从这儿过,就没有数字可拿了,走的就是第二条边
 18
 19 然后是 没点向 右和下 建一条边  费用0,流量k
 20 */
 21 #include<iostream>
 22 #include<queue>
 23 #include<cstring>
 24 #include<cstdio>
 25 #define N 50000
 26 #define M 5005
 27 #define Max 0x3f3f3f3f
 28 using namespace std;
 29 class EDGE
 30 {
 31 public:
 32    int u, v, c, f;
 33    int next;
 34 };
 35 queue<int>q;
 36 EDGE edge[N];
 37 int cap[55][55], n, k;
 38 int pre[N], first[N];
 39 int dist[M], vis[M];
 40 int edgeN;
 41 int s, t;
 42 int maxFlow;
 43
 44 int spfa()
 45 {
 46     memset(dist, 0x3f, sizeof(dist));
 47     memset(vis, 0, sizeof(vis));
 48     memset(pre, -1, sizeof(pre));
 49     dist[s]=0;
 50     q.push(s);
 51     vis[s]=1;
 52     while(!q.empty())
 53     {
 54         int u=q.front();
 55         q.pop();
 56         vis[u]=0;
 57         for(int e=first[u]; e!=-1; e=edge[e].next)
 58         {
 59           int v=edge[e].v;
 60           if(dist[v]>dist[u] + edge[e].c && edge[e].f>0)
 61            {
 62                dist[v]=dist[u] + edge[e].c;
 63                pre[v]=e;
 64                if(!vis[v])
 65                {
 66                      vis[v]=1;
 67                      q.push(v);
 68            }
 69        }
 70     }
 71      }
 72      if(dist[t]==Max)
 73        return 0;
 74      return 1;
 75 }
 76
 77 void updateFlow()
 78 {
 79    int minF=Max;
 80    for(int e=pre[t]; e!=-1; e=pre[edge[e].u])
 81      if(minF>edge[e].f)
 82         minF=edge[e].f;
 83    for(int e=pre[t]; e!=-1; e=pre[edge[e].u])
 84    {
 85       edge[e].f-=minF;
 86       edge[e^1].f+=minF;
 87       maxFlow+=minF*edge[e].c;
 88    }
 89 }
 90
 91 void adde(int u, int v, int c, int f)
 92 {
 93     edge[edgeN].u=u; edge[edgeN].v=v;
 94     edge[edgeN].c=c; edge[edgeN].f=f;
 95     edge[edgeN].next=first[u]; first[u]=edgeN++;
 96
 97     edge[edgeN].u=v; edge[edgeN].v=u;
 98     edge[edgeN].c=-c; edge[edgeN].f=0;
 99     edge[edgeN].next=first[v]; first[v]=edgeN++;
100 }
101
102 int main()
103 {
104    int i, j;
105    while(scanf("%d%d", &n, &k)!=EOF)
106    {
107       maxFlow=0;
108       edgeN=0;
109       memset(first, -1, sizeof(first));
110       s=0; t=n*n*2+1;
111       for(i=1; i<=n; ++i)
112         for(j=1; j<=n; ++j)
113           scanf("%d", &cap[i][j]);
114       adde(s, 1, 0, k);
115       for(i=1; i<=n; ++i)
116         for(j=1; j<=n; ++j)//n*n个节点,拆点之后变成2*n*n个节点
117         {
118            int nb=(i-1)*n+j;
119            adde(2*nb-1, 2*nb, -cap[i][j], 1);//注意:a到a`是建立两条边,但是两条边的费用和容量不一样
120            adde(2*nb-1, 2*nb, 0, k-1);
121            if(j<n)//向右建图
122              adde(2*nb, 2*(nb+1)-1, 0, k);
123            if(i<n)//向下建图
124              adde(2*nb, 2*(nb+n)-1, 0, k);
125     }
126        adde(n*n*2, t, 0, k);
127
128        while(spfa())//建好图之后,直接调用最小费用最大流模板就好了
129           updateFlow();
130        printf("%d\n", -maxFlow);
131    }
132    return 0;
133 }

转载于:https://www.cnblogs.com/hujunzheng/p/3798997.html

poj3422 Kaka's Matrix Travels(最小费用最大流问题)相关推荐

  1. poj 3422 Kaka's Matrix Travels(最小费用最大流)

    题目链接 Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9394   Accep ...

  2. POJ3422 Kaka's Matrix Travels

    描述 On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels wi ...

  3. pku 3422 Kaka's Matrix Travels 最大费用最大流

    http://poj.org/problem?id=3422 /* 题意:给定一个n*n的矩形方格,要求从(1,1)出发,只能往右下角走,(i + 1,j) 或者 (i + n,j)每次走完将格子里面 ...

  4. Kaka's Matrix Travels(减弱版) DP版

    Kaka's Matrix Travels(减弱版) Time Limit:5000MS  Memory Limit:65536K Total Submit:15 Accepted:8 Descrip ...

  5. mysql最小费用最大流问题_最小费用最大流问题

    复杂网络中,单源单点的最小费用最大流算法(MCMF)应用广泛. 在实际网络问题中,不仅考虑从 Vs到 Vt的流量最大,还要考虑可行流在网络传送过程中的费用问题,这就是网络的最小费用最大流问题. 最小费 ...

  6. 数学建模常用Matlab/Lingo/c代码总结系列——最小费用最大流问题

    例 19(最小费用最大流问题)(续例18)由于输油管道的长短不一或地质等原因, 使每条管道上运输费用也不相同,因此,除考虑输油管道的最大流外,还需要考虑输油 管道输送最大流的最小费用.图 8 所示是带 ...

  7. 最小费用最大流问题与算法实现(Bellman-Ford、SPFA、Dijkstra)

    摘要 今日,对最小费用最大流问题进行了一个简单的研究,并针对网上的一些已有算法进行了查找和研究.博客和资料很多,但是留下的算法很多运行失败.出错,或者意义不明.这里,个人对其中的Bellman-For ...

  8. 最小费用最大流问题详解

    最小费用最大流问题 一.问题描述 在网络中求一个最大流f,使流的总输送费用最小. b(f)=∑(vi,vj)bijfijb(f) = \sum\limits_{(v_i,v_j)} b_{ij} f_ ...

  9. 网络流:最小费用最大流问题

    前置知识:最大流问题 最小费用最大流问题: 在最大流问题基础上,为每条边赋值单位流量的花费.求解保证最大流时,最小花费为多少.(因为最大流可以有多种流分配方案) 以EK算法为基础,在bfs时增加求最短 ...

最新文章

  1. Git:与GitHub搭配及SSH登录
  2. 微信小程序出现【需要进行身份验证】弹框解决方法
  3. python 二分类的实例_keras分类之二分类实例(Cat and dog)
  4. pthread_join()函数理解
  5. 如何快速REPAIR TABLE
  6. 网络服务考试(通过率50%)
  7. devops 开源工具链_使用开源工具构建DevOps管道的初学者指南
  8. rpm常用命令集合1
  9. 关于超过255台电脑的内网IP规划问题
  10. CPP_template
  11. 网易高并发优化 | 公开课-02
  12. 微信号php756,微信机器人开发者常说的“提62”是什么?微信62数据是什么意思?...
  13. 数据库SQL调优的几种方式
  14. 好用的蓝牙管理工具推荐,帮您优雅管理蓝牙功能!
  15. Base64编码工具类
  16. python下载腾讯视频_使用python 下载 mp4格式的腾讯视频
  17. unity5.0安卓开发环境配置
  18. Newton冷却定理微分数学公式推导
  19. ipv6地址分类 java_IPv6的本地联网地址计算方法详解
  20. mac linux 笔记

热门文章

  1. ssh是什么_【科普】SSH都不懂,还搞什么网络
  2. stringutils 用哪个包 apache spring_spring整合mq、jsonp跨越、httpclient工具的使用
  3. docker redis:6.2.6
  4. 通用mapper如何处理多表条件查询通过list封装(强烈不推荐)(一对一,一对多)
  5. 记录——oracle数据库备份
  6. python加载模型包占用内存多大_如何保持Keras模型加载到内存中并在需要时使用它? - python...
  7. xbox one s驱动_续航800公里 体验6座SUV理想ONE
  8. mysql in 按顺序排序_mysql in 排序 也可以按in里面的顺序来排序
  9. deepin中mysql数据库的连接_教你如何典雅的用Python连接MySQL数据库
  10. jq之slidedown()