zoukankan      html  css  js  c++  java
  • codevs 1227 方格取数 2

    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 1

    1 2 3

    0 2 1

    1 4 2

    Sample Output

    11

    Data 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的边即可(自己想一想,不难的)。然后跑一遍最大费用最大流即可。

        代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
     7 #define maxn 100010
     8 #define INF (1<<28)
     9 #define r(j) (j^1)
    10 
    11 using namespace std;
    12 typedef long long llg;
    13 
    14 int head[maxn],to[maxn],next[maxn],c[maxn],f[maxn],ff[maxn];
    15 int n,k,tt=1,ans,dis[maxn],d[maxn],fa[maxn],d2[maxn],l,r,hui;
    16 bool w[maxn];
    17 
    18 void link(int x,int y,int z,int o){
    19     to[++tt]=y;next[tt]=head[x];head[x]=tt;
    20     to[++tt]=x;next[tt]=head[y];head[y]=tt;
    21     c[tt-1]=z; f[tt-1]=o; f[tt]=-o;
    22 }
    23 
    24 bool spfa(){
    25     for(int i=1;i<=hui;i++) dis[i]=-1,d2[i]=INF;
    26     dis[1]=0; l=r=0; d[r++]=1; w[1]=1;
    27     while(l!=r){
    28         int u=d[l++]; l%=maxn; w[u]=0;
    29         for(int i=head[u],v;v=to[i],i;i=next[i])
    30             if(c[i]>0 && dis[v]<dis[u]+f[i]){
    31                 dis[v]=dis[u]+f[i];
    32                 d2[v]=min(d2[u],c[i]);
    33                 fa[v]=u; ff[v]=i;
    34                 if(!w[v]){
    35                     w[v]=1;d[r++]=v;
    36                     r%=maxn;
    37                 }
    38             }
    39     }
    40     if(dis[hui]==-1) return 0;
    41     ans+=dis[hui]*d2[hui];
    42     int now=hui;
    43     while(now!=1){
    44         c[ff[now]]-=d2[hui];
    45         c[r(ff[now])]+=d2[hui];
    46         now=fa[now];
    47     }
    48     return 1;
    49 }
    50 
    51 int main(){
    52     File("a");
    53     scanf("%d%d",&n,&k);hui=n*n<<1;
    54     for(int i=1,now=1,x;i<=n;i++)
    55         for(int j=1;j<=n;j++,now++){
    56             scanf("%d",&x);
    57             link(now,now+n*n,1,x); link(now,now+n*n,k-1,0);
    58             if(j<n) link(now+n*n,now+1,k,0);
    59             if(i<n) link(now+n*n,now+n,k,0);
    60         }
    61     while(spfa());
    62     printf("%d",ans);
    63     return 0;
    64 }
  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/5567608.html
Copyright © 2011-2022 走看看