codevs 1227 方格取数 2
2016-06-07 17:08
435 查看
Description
给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大Input Description
第一行两个数n,k(1<=n<=50, 0<=k<=10)接下来n行,每行n个数,分别表示矩阵的每个格子的数
Output Description
一个数,为最大和Sample Input
3 11 2 3
0 2 1
1 4 2
Sample Output
11Data Size & Hint
1<=n<=50, 0<=k<=10恩......说实话这道题应该是网络流的题,但是想了半天也没有想出来......膜了网上的题解后才发现,这是道费用流的题(亏我一直在想怎么控制和最大)
知道这是费用流的以后就很好办了。由于每个点可能有两种情况,即之前没经过这个点时走到这个点,和之前已经走过这个点了。前一种情况需要计算贡献,而后一种情况则不需要。
然后,我们考虑如何控制这两种情况。我们可以将每个点x拆开,拆为x1与x2。这样每次从x1走到x2时就可以把这个点的贡献给算进去。由于前一种情况只有一次,而后一种情况最多有k-1次,所以我们在x1与x2之间连两种边,一种容量为1,费用为这个节点的值(对应第一种情况),另一种容量为k-1,费用为0(对应第二种情况)。然后考虑这个点往下和往右连边,假设这两个点分别为y,z,那么从x2往y1、z1分别连一条容量为k,费用为0的边即可(自己想一想,不难的)。然后跑一遍最大费用最大流即可。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) #define maxn 100010 #define INF (1<<28) #define r(j) (j^1) using namespace std; typedef long long llg; int head[maxn],to[maxn],next[maxn],c[maxn],f[maxn],ff[maxn]; int n,k,tt=1,ans,dis[maxn],d[maxn],fa[maxn],d2[maxn],l,r,hui; bool w[maxn]; void link(int x,int y,int z,int o){ to[++tt]=y;next[tt]=head[x];head[x]=tt; to[++tt]=x;next[tt]=head[y];head[y]=tt; c[tt-1]=z; f[tt-1]=o; f[tt]=-o; } bool spfa(){ for(int i=1;i<=hui;i++) dis[i]=-1,d2[i]=INF; dis[1]=0; l=r=0; d[r++]=1; w[1]=1; while(l!=r){ int u=d[l++]; l%=maxn; w[u]=0; for(int i=head[u],v;v=to[i],i;i=next[i]) if(c[i]>0 && dis[v]<dis[u]+f[i]){ dis[v]=dis[u]+f[i]; d2[v]=min(d2[u],c[i]); fa[v]=u; ff[v]=i; if(!w[v]){ w[v]=1;d[r++]=v; r%=maxn; } } } if(dis[hui]==-1) return 0; ans+=dis[hui]*d2[hui]; int now=hui; while(now!=1){ c[ff[now]]-=d2[hui]; c[r(ff[now])]+=d2[hui]; now=fa[now]; } return 1; } int main(){ File("a"); scanf("%d%d",&n,&k);hui=n*n<<1; for(int i=1,now=1,x;i<=n;i++) for(int j=1;j<=n;j++,now++){ scanf("%d",&x); link(now,now+n*n,1,x); link(now,now+n*n,k-1,0); if(j<n) link(now+n*n,now+1,k,0); if(i<n) link(now+n*n,now+n,k,0); } while(spfa()); printf("%d",ans); return 0; }
相关文章推荐
- clone代码
- 2015年中国软件测试现状调查报告!
- shiro简介
- LeNet、AlexNet、VGG、ZF
- 浅谈软件架构师的素质与职责
- Html5 Checkbox多种状态切换
- IncompleteElementException: Could not find result map java.util.HashMap
- ubuntu中apache页面权限控制
- 神奇的书签
- Ormlite一对多配置
- 【正则表达式】不要写通配嵌套的正则表达式!
- linux_2.6内核内存缓冲与I/O调度机制:
- clojure用gen-class来实现java接口,及java中测试
- Jersey 2.17 + Tomcat + Maven 构建restful service 实例
- jni
- android 常用代码
- Linux常用网络测试命令
- webstorm 实现 项目上传到github
- 时间拉链表用法
- 单例模式的几种写法