zoukankan      html  css  js  c++  java
  • codevs1227:方格取数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
    题目

    芒果君:刚学的拆点,为数不多的自己写出来的网络流……理解题意后我们发现有以下几个要点:进行K次增广路;只能向右向下走;经过格点但可以不取数。那我们可以把每个格点拆成无权和有权的两个点。从其他点(同一位置有两个)走到该点,就走到无权点,流量视为inf,费用为0;当然也可以从同一点的无权走向有权,就是取出该数,只能取一次,流量是1,费用为负点权。左上连源点,右下连汇点。套KM的板子,最后的费用取相反数就是最大价值。注意建反边的费用是正边的相反数!

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<vector>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<stack>
     11 #include<bitset>
     12 #include<string>
     13 #define maxn 20010
     14 using namespace std;
     15 typedef long long ll;
     16 const int inf=1<<29;
     17 queue<int>Q;
     18 int n,cnt,hl[maxn],s,t,k,vis[maxn],dis[maxn],pre[maxn],flow[maxn],id[maxn],tot;
     19 inline int cal(int x,int y){return (x-1)*n+y;}
     20 struct Edge{
     21     int u,v,c,f,ne,ctr;
     22 }e[200010];
     23 void add(int u,int v,int c,int f,int ctr)
     24 {
     25     e[++cnt].u=u;
     26     e[cnt].v=v;
     27     e[cnt].c=c;
     28     e[cnt].f=f;
     29     e[cnt].ctr=cnt+ctr;
     30     e[cnt].ne=hl[u];
     31     hl[u]=cnt;
     32 }
     33 bool bfs()
     34 {
     35     for(int i=0;i<=n*n*2+1;++i) dis[i]=inf,pre[i]=-1,vis[i]=0;
     36     dis[s]=pre[s]=0;
     37     flow[s]=inf;
     38     Q.push(s);
     39     while(!Q.empty()){
     40         int x=Q.front();
     41         Q.pop();
     42         vis[x]=0;
     43         for(int i=hl[x];i;i=e[i].ne){
     44             int v=e[i].v,c=e[i].c,w=e[i].f;
     45             if(c&&dis[v]>dis[x]+w){
     46                 dis[v]=dis[x]+w;
     47                 pre[v]=x;
     48                 id[v]=i;
     49                 flow[v]=min(flow[x],c);
     50                 if(!vis[v]){
     51                     vis[v]=1;
     52                     Q.push(v);
     53                 }
     54             }
     55         }
     56     }
     57     return dis[t]<inf;
     58 }
     59 int KM()
     60 {
     61     int ret(0);
     62     while(bfs()){
     63         tot++;
     64         if(tot>k) break;
     65         int now=t;
     66         while(now!=s){
     67             int i=id[now],j=e[i].ctr;
     68             e[i].c-=flow[t];
     69             e[j].c+=flow[t];
     70             now=pre[now];
     71         }
     72         ret+=flow[t]*dis[t];
     73     }
     74     return ret;
     75 }
     76 int main()
     77 {
     78     int w;
     79     scanf("%d%d",&n,&k);
     80     for(int i=1;i<=n;++i) 
     81         for(int j=1;j<=n;++j){
     82             scanf("%d",&w);
     83             add(cal(i,j),n*n+cal(i,j),1,-w,1);
     84             add(n*n+cal(i,j),cal(i,j),0,w,-1);
     85         }
     86     puts("");
     87     for(int i=1;i<=n;++i)
     88         for(int j=1;j<=n;++j){
     89             if(j+1<=n){
     90                 add(cal(i,j),cal(i,j+1),inf,0,1);
     91                 add(cal(i,j+1),cal(i,j),0,0,-1);
     92                 add(n*n+cal(i,j),cal(i,j+1),1,0,1);
     93                 add(cal(i,j+1),n*n+cal(i,j),0,0,-1);
     94             }
     95             if(i+1<=n){
     96                 add(cal(i,j),cal(i+1,j),inf,0,1);
     97                 add(cal(i+1,j),cal(i,j),0,0,-1);
     98                 add(n*n+cal(i,j),cal(i+1,j),1,0,1);
     99                 add(cal(i+1,j),n*n+cal(i,j),0,0,-1);
    100             }
    101         }
    102     s=0,t=n*n*2+1;
    103     add(0,1,inf,0,1);add(1,0,0,0,-1);
    104     add(n*n,t,inf,0,1);add(t,n*n,0,0,-1);
    105     add(t-1,t,inf,0,1);add(t,t-1,0,0,-1);
    106     printf("%d
    ",-KM());
    107     return 0;
    108 }
  • 相关阅读:
    02-SpringCloud 基础框架搭建
    01-SpringCloud 理论
    ES7 语法详解(async 与 await(重点))
    ES6 语法详解(Set和Map(重点))
    ES6 语法详解(对象扩展)
    ES6 语法详解(数组扩展)
    ES6 语法详解(数值扩展)
    ES6 语法详解(字符串扩展)
    ES6 语法详解(class关键字)
    ES6 语法详解(Generator函数)
  • 原文地址:https://www.cnblogs.com/12mango/p/7718309.html
Copyright © 2011-2022 走看看