描述

On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking care that the rook moves only to the right or down. Kaka adds the number to SUM in each grid the rook visited, and replaces it with zero. It is not difficult to know the maximum SUM Kaka can obtain for his first travel. Now Kaka is wondering what is the maximum SUM he can obtain after his Kth travel. Note the SUM is accumulative during theK travels.

输入

The first line contains two integers N and K (1 ≤ N ≤ 50, 0 ≤ K ≤ 10) described above. The following N lines represents the matrix. You can assume the numbers in the matrix are no more than 1000.

输出

The maximum SUM Kaka can obtain after his Kth travel.

样例输入

3 2
1 2 3
0 2 1
1 4 2

样例输出

15

来源

POJ Monthly--2007.10.06, Huang, Jinsong

正解:网络流(最小费用最大流)

解题报告:

2016年北京大学信息学奥赛训练营上机考核第三场 B题

  大致题意是给定一个网格图,从左上角走到右下角,并且拿走经过的格子里面的数,只能往右或者往下走。总共走k次,问总和最大是多少。

  因为以前做过一道NOIP的类似题目,所以一见到这道题就马上想DP,结果发现不对。NOIP那道题是双线程DP,空间和时间都是允许的,而这道题是k次,要开2*k维,显然会炸。

  机智的我马上想起以前在codevs上面看过这道题,似乎是一模一样的。并且记得是网络流。然而最后没打出来,并不会建模,还是网络流题目做太少了。

  这道题其实很简单,模型也很容易想到。可以看出本题就是求最大费用最大流,我们把图里的数字改成负数就可以变成最小费用最大流,最后取相反数就可以了。

  我参考了这份博客,讲的还比较清楚:http://blog.csdn.net/qq172108805/article/details/7857503

  

  如上图所示,我们把一个点拆成两个点,并且用两条边相连,一条权值为这个点的权值,流量为1;另一条权值为0,流量为k-1(反向边都要分别添加)

  再加上点之间的相连,容易想到这样建模可以达到题目要求的目的

  代码如下:

  1 //It is made by jump~
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <ctime>
  9 #include <vector>
 10 #include <queue>
 11 #include <map>
 12 #ifdef WIN32
 13 #define OT "%I64d"
 14 #else
 15 #define OT "%lld"
 16 #endif
 17 using namespace std;
 18 typedef long long LL;
 19 const int MAXN = 60;
 20 const int MAXD = 5011;
 21 const int MAXM = 100011;
 22 const int inf = 2000000000;
 23 int n,k;
 24 int a[MAXN][MAXN];
 25 int first[MAXD],dis[MAXD];
 26 bool pd[MAXD];
 27 int pre[MAXD];
 28 int ecnt=1;
 29 int s,t;
 30 int ans;
 31 queue<int>Q;
 32
 33 struct edge{
 34     int to,f,next,u;
 35     int w;
 36 }e[MAXM];
 37
 38 inline int getint()
 39 {
 40     int w=0,q=0;
 41     char c=getchar();
 42     while((c<'0' || c>'9') && c!='-') c=getchar();
 43     if (c=='-')  q=1, c=getchar();
 44     while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
 45     return q ? -w : w;
 46 }
 47
 48 inline void link(int x,int y,int w,int z){
 49     e[++ecnt].next=first[x]; first[x]=ecnt; e[ecnt].to=y; e[ecnt].f=z; e[ecnt].w=w; e[ecnt].u=x;
 50     e[++ecnt].next=first[y]; first[y]=ecnt; e[ecnt].to=x; e[ecnt].f=0; e[ecnt].w=-w; e[ecnt].u=y;
 51 }
 52
 53 inline int spfa(){//EK
 54     //根据边权跑最短路
 55     while(!Q.empty()) Q.pop();
 56     memset(pd,0,sizeof(pd));
 57     //memset(pre,0,sizeof(pre));
 58     //memset(flow,0,sizeof(flow));
 59     for(int i=0;i<=t;i++) dis[i]=inf,pre[i]=-1;
 60     pd[s]=1; Q.push(s); dis[s]=0;
 61     while(!Q.empty()){
 62     int u=Q.front(); Q.pop(); pd[u]=0;
 63     //if(u==t) break;
 64     for(int i=first[u];i;i=e[i].next) {
 65         if(e[i].f>0) {
 66         int v=e[i].to;
 67         if(dis[v]>dis[u]+e[i].w) {//限制流
 68             dis[v]=dis[u]+e[i].w;
 69             pre[v]=i;
 70             if(!pd[v]) { Q.push(v); pd[v]=1; }
 71         }
 72         }
 73     }
 74     }
 75     if(dis[t]==inf) return -1;
 76     return 1;
 77 }
 78
 79 inline int update(){
 80     int total=0; int f=inf;
 81     for(int i=pre[t];e[i].u!=s;i=pre[e[i].u]) f=min(f,e[i].f);
 82
 83     for(int i=pre[t];e[i].u!=s;i=pre[e[i].u]){
 84     total+=e[i].w*f;
 85     e[i].f-=f;
 86     e[i^1].f+=f;
 87     }
 88
 89     return total;
 90 }
 91
 92 inline void solve(){
 93     while(scanf("%d%d",&n,&k)!=EOF) {
 94     for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)  a[i][j]=getint();
 95     ecnt=1;
 96     memset(first,0,sizeof(first));
 97     for(int i=1;i<=n;i++)
 98         for(int j=1;j<=n;j++) {
 99         int now=(i-1)*n+j-1;
100         link(now*2,now*2+1,-a[i][j],1); link(now*2,now*2+1,0,k-1);//拆成两个点,并且连边
101         }
102
103     for(int i=1;i<=n;i++) //向右连边
104         for(int j=1;j<n;j++) {//最后一列无需连边
105         int now=(i-1)*n+j-1;
106         link(now*2+1,now*2+2,0,k);
107         }
108
109     for(int i=1;i<n;i++) //向下连边
110         for(int j=1;j<=n;j++) {//最后一行无需连边
111         int now=(i-1)*n+j-1;
112         link(now*2+1,(now+n)*2,0,k);
113         }
114
115     s=n*n*2; t=s+1;
116     link(s,0,0,k); link(s-1,t,0,k);
117
118     ans=0;
119     while(1) {
120         int daan=spfa();
121         if(daan==-1) break;
122         ans+=update();
123     }
124     printf("%d\n",-ans);
125     }
126
127 }
128
129 int main()
130 {
131     solve();
132     return 0;
133 }

转载于:https://www.cnblogs.com/ljh2000-jump/p/5567551.html

POJ3422 Kaka's Matrix Travels相关推荐

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

    1 /* 2 poj3422 Kaka's Matrix Travels 3 不知道 k次 dp做为什么不对??? 4 看了大牛的代码,才知道还可以这样做! 5 开始没有理解将a 和 a' 之间建立怎 ...

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

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

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

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

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

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

  5. POJ - 3422 Kaka's Matrix Travels(网络流-最大费用最大流+拆点法)

    题目链接:点击查看 题目大意:K取方格数,是在一个N*N的矩形网格中,每个格子里都写着一个整数.可以从左上角到右下角安排K条路线,每一步只能往下或往右,沿途经过的格子中的整数会被取走.若多条路线重复经 ...

  6. POJ 3422 Kaka's Matrix Travels

    题目链接:ヾ(≧∇≦*)ゝ 大致题意:给你一个\(n*n\)的矩阵从\((1,1)\)出发,到\((n,n)\)结束,只能走右边或左边.每个点在被走过之后权值变成0,问走\(k\)次后,能获得的最大值 ...

  7. POJ 3422 Kaka's Matrix Travels | 费用流

    最初的想法是这样的,先走一条最大费用流,沿路回来把所有的点的权值更新为0,然后再跑最大费用流,嗯,好像很对.后来想想,这完全不符合网络流的思想啊Orz. 题意: 一个矩阵,每个grid都有一个权值.从 ...

  8. hdu Kaka's Matrix Travels(最小费用最大流)

    把题意写一下:  给你一个n*n的矩阵,每个格子都有一个非负整数,从左上角走到右下角,收集走过的数字,累加,但是只能向右或者向下走,走过之后数字就变为0,让你求从左上角到右下角,走k次之后,所得的最大 ...

  9. poj 3422 Kaka's Matrix Travels 费用流

    题目链接 给一个n*n的矩阵, 从左上角出发, 走到右下角, 然后在返回左上角,这样算两次. 一共重复k次, 每个格子有值, 问能够取得的最大值是多少, 一个格子的值只能取一次, 取完后变为0. 费用 ...

最新文章

  1. 记录华为P40Pro+系列相机参数总结
  2. GDCM:将一个DICOM文件转换为另一个DICOM文件测试
  3. C语言链表返回第n个到最后的节点的算法(附完整源码)
  4. 山羊与汽车游戏的实验算法
  5. mysql+性能优化+命令_MySQL 性能优化及常用命令
  6. 英特尔发布至强E-2300服务器处理器,比上一代性能提高17%
  7. Farey Sequence(欧拉函数板子题)
  8. 爬取常用的网站,整理成API:中国联通,大众点评,IT桔子,拉勾网,猫眼电影,人人贷......
  9. mysql_num_fielfs_mysql_num_fields
  10. android package.xml,文件没问题的情况下not read packageName from xxx\AndroidManifest.xml?
  11. matlab图像光照效果模拟
  12. 搜狗输入法不错,附带的进程需要一个个把exe文件重命名
  13. Linux命令 常见命令 详细分类
  14. An internal error occurred during: Validating ***.
  15. PLC应用关于自动化控制中离散PID模型的理论分析
  16. 数据库基础知识ACID,隔离级别RC,RR,RU,SERIALIZABLE,Phantom Rows幻读,解决幻读,脏读dirty read
  17. 【2023/05/13】NP完备
  18. 自动驾驶中常见的位姿表示和坐标系问题
  19. 不知道音乐降噪如何实现?快来看看这几种音乐降噪的操作
  20. 推荐一个好用的免费简历word模板

热门文章

  1. [SOLO ]SOLO: Segmenting Objects by Locations代码解读笔记(ECCV. 2020)
  2. 简单的通过两点坐标判断当前两点间距离 ----百度地图 苹果定位
  3. 小道消息 放弃了国企铁饭碗,离开了民企 996,我在外企做测试开发
  4. android 竞品分析工具对比
  5. 硕盟type c六合一拓展坞|苹果电脑转换器
  6. 近距离观看WhatsUp Gold Virtualization
  7. 微信小程序教程-调用服务器接口
  8. HTML5新标签与特性
  9. NGUI 中,长技能图标显示技能Tips的核心代码
  10. 再次碰见问题:fatal error LNK1181: 无法打开输入文件“xxx.lib”