zoukankan      html  css  js  c++  java
  • 【网络流24题】方格取数问题

    【问题描述】

    在一个有m * n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。对于给定的方格棋盘,按照取数要求编程找出总和最大的数。

    【输入格式】

    第1 行有2 个正整数m和n,分别表示棋盘的行数和列数。
    接下来的m行,每行有n个正整数,表示棋盘方格中的数。

    【输出格式】

    将取数的最大总和输出

    【输入样例】

    3 3
    1 2 3
    3 2 3
    2 3 1

    【输出样例】

    11

    【数据范围】

    1<=N,M<=30

    正解:网络流

    解题报告:对图进行黑白染色,然后就变成了一个二分图,然后就是套结论二分图最大独立集等于权值和减去最小割。

     1 #include <iostream>
     2 #include <iomanip>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <cstring>
     7 #include <string>
     8 #include <algorithm>
     9 #define RG register
    10 #define MIN(a,b) a<b?a:b
    11 const int N = 10000;
    12 const int inf = 2147483641;
    13 
    14 using namespace std;
    15 
    16 int gi(){
    17     char ch=getchar();int x=0;
    18     while(ch<'0' || ch>'9') ch=getchar();
    19     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    20     return x;
    21 }
    22 
    23 struct date{
    24     int from,to,val,fa;
    25 }nn[N];
    26 
    27 int h[N],vis[N],f[N],head[N],cnt=1,jl[N],gg;
    28 int S,T,ans,kk;
    29 
    30 void link(int l,int r,int val){
    31     nn[++cnt]=(date){l,r,val,head[l]},head[l]=cnt;
    32     nn[++cnt]=(date){r,l,0,head[r]},head[r]=cnt;
    33     return;
    34 }
    35 
    36 int bfs(){
    37     for (RG int i=1; i<=gg; ++i)
    38         vis[jl[i]]=0;
    39     int l=0,r=1;gg=0;
    40     h[1]=0,vis[0]=1;
    41     while(l<r){
    42         ++l;
    43         for (RG int i=head[h[l]]; i; i=nn[i].fa){
    44             if (nn[i].val==0 || vis[nn[i].to]) continue;
    45             vis[nn[i].to]=vis[h[l]]+1,jl[++gg]=nn[i].to;
    46             h[++r]=nn[i].to;
    47         }
    48         if (vis[T]) return 1;
    49     }
    50     return 0;
    51 }
    52 
    53 int dinic(int xh,int sum){
    54     if (xh==T) return sum;
    55     RG int s=0;
    56     for (RG int i=head[xh]; i; i=nn[i].fa){
    57         if (vis[nn[i].to]!=vis[xh]+1 || nn[i].val==0) continue;
    58         RG int tmp=dinic(nn[i].to,MIN(sum,nn[i].val));
    59         nn[i].val-=tmp,nn[i^1].val+=tmp;
    60         s+=tmp,sum-=tmp;
    61         if (sum==0) break;
    62     }
    63     if (s==0) vis[xh]=-1;
    64     return s;
    65 }
    66 
    67 int main(){
    68     freopen("x.in","r",stdin);
    69     freopen("x.out","w",stdout);
    70     int m=gi(),n=gi();T=n*m+1;
    71     for (RG int i=1; i<=m; ++i){
    72         RG int k=(i-1)*n;
    73         for (RG int j=1; j<=n; ++j){
    74             f[k+j]=gi();kk+=f[k+j];
    75             if ((i+j-1)&1){
    76                 link(S,k+j,f[k+j]);
    77                 if (j<n)
    78                     link(k+j,k+j+1,inf);
    79                 if (i<m)
    80                     link(k+j,k+j+n,inf);
    81                 if (i>1)
    82                     link(k+j,k+j-n,inf);
    83                 if (j>1)
    84                     link(k+j,k+j-1,inf);
    85             }
    86             else
    87                 link(k+j,T,f[k+j]);
    88         }
    89     }
    90     while(bfs()) ans+=dinic(S,inf);
    91     printf("%d",kk-ans);
    92     return 0;
    93 }
  • 相关阅读:
    分布式事务基本概念
    rocketmq源码分析3-consumer消息获取
    Mac下的Eclipse不能记住工作空间问题
    rocketmq源码分析2-broker的消息接收
    rocketmq源码分析1-benchmark学习
    metrics
    slf4j与logback对接是如何将日志写到控制台的
    Spring AOP
    hibernate数据库连接池,常用配置
    动态代理
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6427475.html
Copyright © 2011-2022 走看看