poj 3422 Kaka's Matrix Travels
来源:互联网 发布:蜂窝数据打不开 编辑:程序博客网 时间:2024/05/24 23:16
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 21 2 30 2 11 4 2
Sample Output
15
Source
提示
题意:有个n*n(1<=n<=50)带数值的矩阵,左上角是起点,右下角是终点,只能向下或向右,走过一次的地方数值就为零,问走k(0<=k<=10)次最多能得到多少数值。
思路:
看了别人的代码整理出来的,实际上并没有理解透彻。。。
1.拆点,一个点拆成两个,一个是只能走过一次的且带值的点(编号i),另一个就是值为0可以走k次或无限次的点(编号n*n+i)。
2.每个点(以值为0的点为基准)与下边和右边的点(这里又以带值的点为基准)建立边,这样一个图就完成了。不过还需要添加超级源点和终点。
3.因为是求最大值所以最短路算法要改成最长路。
步骤可以理解,还有部分细节还是不很清楚,看样子还有得学。。。
示例程序
Source CodeProblem: 3422Code Length: 2138BMemory: 1608KTime: 63MSLanguage: GCCResult: Accepted#include <stdio.h>#include <string.h>struct{ int v,next,cost,num,pos;}w[20000];int h[5002],numw,map[50][50],n,k,pre[5002];void insert(int u,int v,int cost,int num){ w[numw].v=v; w[numw].cost=cost; w[numw].next=h[u]; w[numw].num=num; w[numw].pos=numw+1;//pos貌似是与反向边建立对应关系 h[u]=numw; numw++; w[numw].v=u;//反向边 w[numw].cost=-cost; w[numw].next=h[v]; w[numw].num=0; w[numw].pos=numw-1; h[v]=numw; numw++;}int spfa(){ int i,q[200000],v[5002],d[5002],pos,f=0,top=0; memset(v,0,sizeof(v)); memset(d,-1,sizeof(d)); d[0]=0; v[0]=1; q[top]=0; top++; while(f<top) { v[q[f]]=0; for(i=h[q[f]];i!=-1;i=w[i].next) { pos=w[i].v; if(w[i].num!=0&&d[pos]<d[q[f]]+w[i].cost) { d[pos]=d[q[f]]+w[i].cost; pre[pos]=i; if(v[pos]==0) { q[top]=pos; top++; v[pos]=1; } } } f++; } if(d[2*n*n+1]!=-1) { return 1; } else { return 0; }}int maxflow(){ int i,pos,sum=0; while(spfa()==1) { for(i=2*n*n+1;i!=0;i=w[w[pos].pos].v) { pos=pre[i]; w[pos].num=w[pos].num-1;//似乎因为流量固定为一的关系少了循环判断 w[w[pos].pos].num=w[w[pos].pos].num+1; sum=sum+w[pos].cost; } } return sum;}int main(){ int i,i1,x,y; scanf("%d %d",&n,&k); memset(h,-1,sizeof(h)); numw=0; for(i=0;n>i;i++) { for(i1=0;n>i1;i1++) { scanf("%d",&map[i][i1]); } } for(i=0;n>i;i++) { for(i1=0;n>i1;i1++) { x=i*n+i1+1; y=n*n+x; insert(x,y,map[i][i1],1);//拆点,加边 insert(x,y,0,k); if(i!=n-1)//矩阵连边 { insert(y,x+n,0,k); } if(i1!=n-1) { insert(y,x+1,0,k); } } } insert(0,1,0,k);//增加汇点 insert(2*n*n,2*n*n+1,0,k); printf("%d",maxflow()); return 0;}
- poj 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ-3422-Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- POJ 3422:Kaka's Matrix Travels
- poj 3422 Kaka's Matrix Travels
- POJ 3422 Kaka's Matrix Travels
- poj Kaka's Matrix Travels
- poj 3422 Kaka's Matrix Travels 最小费用最大流
- Kaka's Matrix Travels POJ 3422 最大费用流
- POJ 3422 Kaka's Matrix Travels (最大费用最大流)
- POJ 3422 Kaka's Matrix Travels (最大费用最大流)
- POJ 3422 Kaka's Matrix Travels 费用流
- POJ 3422 Kaka's Matrix Travels 最小费用流
- poj-3422-Kaka's Matrix Travels-最小费用最大流
- 打印出如下图案(菱形)
- Android 常用方法xml大全
- POJ【4047】——Problem D. Garden 线段树
- nyoj67
- HDU 2841 Visible Trees (容斥原理好题)
- poj 3422 Kaka's Matrix Travels
- 数据结构之括号匹配问题
- android studio中R文件丢失错误
- 太极圆圈的Mathematica生成
- 今日头条项目(模仿)
- HTTP协议--浏览器的实现
- CSU 1808 地铁(拆点最短路)
- Unity学习草稿
- Oracle的文件系统