POJ3422 Kaka’s Matrix Travels


Description

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 the K travels.

Input

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.

Output

The maximum SUM Kaka can obtain after his Kth travel.

Sample Input

3 2

1 2 3

0 2 1

1 4 2

Sample Output

15


题意大概就是给你一个n*n的矩形,每一个方格中有一个权值,定义一次行走是从左上角走到右下角,而且每一次移动只能向右边或者下边移动,现在我们要行走k次,并使经过的点集的和最大(每个点值计算一次)

我们很容易想到把每个点的权值作为这个点某种意义上的费用(因为只能计算一次,后面会介绍建图方法),然后我们想最大化这个费用,所以对于这种问题我们可以见图的时候将边权取相反数,然后再跑出最小费用大流的时候将费用取相反数,不难发现这个时候的费用是最大化的

然后我们怎么处理一个节点的边权只能计算一次这个条件呢?

不妨这样思考,我们把一个点i拆成两个点i" role="presentation">ii和i+n∗n" role="presentation">i+n∗ni+n∗n,在i" role="presentation">ii和i+n∗n" role="presentation">i+n∗ni+n∗n之间连接两条弧:

1:一条容量为1,费用为负边权

2:一条容量为k-1,费用为0

我们可以很容易得到如果有流量经过弧2,一定有流量经过弧1,不然就不满足最小费用的性质

又对于两个节点i" role="presentation">ii和j" role="presentation">jj,满足j在i的下边或右边,即i" role="presentation">ii可以到达j" role="presentation">jj,那么我们可以把i+n∗n" role="presentation">i+n∗ni+n∗n连接到j" role="presentation">jj,这样流经i" role="presentation">ii的流量就可以流到j" role="presentation">jj了

现在我们只需要保证源点S流到第一个节点(坐标(1,1))的容量是k就好了

整理一下构图思路:

1 从S" role="presentation">SS连接到第一个节点(1,1)" role="presentation">(1,1)(1,1),容量为k

2 从i" role="presentation">ii到i+n∗n" role="presentation">i+n∗ni+n∗n连接两条弧:

     " role="presentation">          1:一条容量为1,费用为负边权

     " role="presentation">          2:一条容量为k-1,费用为0

3 对于i" role="presentation">ii到可以到达的j" role="presentation">jj连接一条从i+n∗n" role="presentation">i+n∗ni+n∗n到j" role="presentation">jj的边

4 从最后一个节点(n,n)" role="presentation">(n,n)(n,n)连接到汇点T" role="presentation">TT


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define N 100010
#define INF 0x3f3f3f3f
struct Edge{
int u,v,cap,flow,cost;
Edge(int xu,int xv,int xcap,int xflow,int xcost){
u=xu;v=xv;cap=xcap;flow=xflow;cost=xcost;
}
};
struct MCMF{
int s,t,f[N],p[N],d[N];
bool inq[N];
vector<Edge> E;
vector<int> G[N];
void add(int u,int v,int cap,int cost){
E.push_back(Edge(u,v,cap,0,cost));
E.push_back(Edge(v,u,0,0,-cost));
int m=E.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
bool SPFA(int &flow,int &cost){
memset(inq,0,sizeof(inq));
memset(d,0x3f,sizeof(d));
queue<int> Q;Q.push(s);
d[s]=0;f[s]=INF;
while(!Q.empty()){
int u=Q.front();Q.pop();
inq[u]=0;
for(int i=0;i<G[u].size();i++){
Edge e=E[G[u][i]];
if(d[e.v]>d[u]+e.cost&&e.cap>e.flow){
d[e.v]=d[u]+e.cost;
p[e.v]=G[u][i];
f[e.v]=min(f[u],e.cap-e.flow);
if(!inq[e.v]){
Q.push(e.v);
inq[e.v]=1;
}
}
}
}
if(d[t]==INF)return false;
flow+=f[t];cost+=f[t]*d[t];
int u=t;
while(u!=s){
E[p[u]].flow+=f[t];
E[p[u]^1].flow-=f[t];
u=E[p[u]].u;
}
return true;
}
int Min_cost_Max_flow(){
int flow=0,cost=0;
while(SPFA(flow,cost));
return cost;
}
}mcmf;
int n,k;
int g[100][100];
int Index(int x,int y){return (x-1)*n+y;}
int main(){
scanf("%d%d",&n,&k);
mcmf.s=0;mcmf.t=2*n*n+1;
mcmf.add(0,1,k,0);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&g[i][j]);
int tmp=Index(i,j);
mcmf.add(tmp,tmp+n*n,1,-g[i][j]);
mcmf.add(tmp,tmp+n*n,k-1,0);
if(i<n){
int tmp1=Index(i+1,j);
mcmf.add(tmp+n*n,tmp1,INF,0);
}
if(j<n){
int tmp1=Index(i,j+1);
mcmf.add(tmp+n*n,tmp1,INF,0);
}
}
}
mcmf.add(2*n*n,2*n*n+1,k,0);
printf("%d",-mcmf.Min_cost_Max_flow());
return 0;
}

POJ3422 Kaka's Matrix Travels 【费用流】*的更多相关文章

  1. POJ3422 Kaka's Matrix Travels[费用流]

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

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

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

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

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

  4. POJ3422 Kaka's Matrix Travels

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

  5. POJ 3422 Kaka's Matrix Travels(费用流)

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

  6. POJ 3422 Kaka's Matrix Travels

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

  7. POJ 3422 Kaka's Matrix Travels (K取方格数:最大费用流)

    题意 给出一个n*n大小的矩阵,要求从左上角走到右下角,每次只能向下走或者向右走并取数,某位置取过数之后就只为数值0,现在求解从左上角到右下角走K次的最大值. 思路 经典的费用流模型:K取方格数. 构 ...

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

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

  9. POJ3422或洛谷2045 Kaka's Matrix Travels

    POJ原题链接 洛谷原题链接 很裸的费用流. 将每个点\(x\)拆成\(x_1,x_2\),并从\(x_1\)向\(x_2\)连一条容量为\(1\),费用为该点的权值的边,以及一条容量为\(+\inf ...

随机推荐

  1. 纯js提交get和post请求

    get function get(URL, PARAMS) { var temp = document.createElement("form"); temp.method = & ...

  2. Unity教程之-UGUI一个优化效率小技巧

    无意间发现了一个小技巧.如下图所示,可以发现UGUI的Image组件的RaycastTarget勾选以后会消耗一些效率,为了节省效率就不要勾选它了,不仅Image组件Text组件也有这样的问题. 一般 ...

  3. ABP 学习问题集锦

    一:Update-Database : 无法将“Update-Database”项识别为 cmdlet.函数.脚本文件或可运行程序的名称的问题 解决: 这是因为没有引用EntityFramework命 ...

  4. 【转】VIM 中设置Tab

    灵活操作 Vim 中的 Tabsgaleki post @ 2007年11月16日 05:07PM in Vim Tips with tags: vim tabs Vim 支持 Tabs,也就是标签页 ...

  5. Kali之aircrack-ng

    本机装好设备及驱动 电脑本机装好Realtek RTL8187 Wireless驱动连接好USB无线驱动 把设备转接给虚拟机 win+R,启动VMware USB Arbitration Servic ...

  6. UVA-10917 Walk Through the Forest (dijkstra+DP)

    题目大意:n个点,m条边的无向图.一个人从起点到终点按照下面的走法:从A走向B当A到终点的最小距离比B到终点的最小距离大时.问从起点到终点有多少路径方案. 题目分析:先用dijkstra预处理出终点到 ...

  7. SPOJ 694 && SPOJ 705 (不重复子串个数:后缀数组)

    题意 给定一个字符串,求它的所有不重复子串的个数 思路 一个字符串的子串都必然是它的某个后缀的前缀.对于每一个sa[i]后缀,它的起始位置sa[i],那么它最多能得到该后缀长度个子串(n-sa[i]个 ...

  8. Day16 Django深入讲解

    参考博客: http://www.cnblogs.com/yuanchenqi/articles/6083427.html http://www.cnblogs.com/yuanchenqi/arti ...

  9. Ansible 小手册系列 十七(特性模块)

    异步操作和轮询 --- # Requires ansible 1.8+ - name: 'YUM - fire and forget task' yum: name=docker-io state=i ...

  10. IE中的if语句--实现不同版本IE浏览器不同html代码 (转)

    在很多html代码中常常可以看到很多的IE的条件语句,有时候很不明白他们的意思,其实这是为了能与低版本浏览器实现更好的兼容,例如在制作纯CSS的级联菜单时,由于在IE6中只有<a>支持伪类 ...