• codevs1907 方格取数 3


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

    输入描述 Input Description

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

    输出描述 Output Description

    将取数的最大总和输出

    样例输入 Sample Input

    3 3
    1 2 3
    3 2 3
    2 3 1

    样例输出 Sample Output

    11

    数据范围及提示 Data Size & Hint

    n,m<=30

    正解:网络流

    解题报告:

      同HDU1565,我的题解的传送门:http://www.cnblogs.com/ljh2000-jump/p/5756667.html

     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXN = 501;
    21 const int MAXM = 500011;
    22 const int inf = (1<<30);
    23 int m,n,sum,S,T,ecnt,ans;
    24 int a[MAXN][MAXN],deep[MAXN*MAXN];
    25 int first[MAXN*MAXN];
    26 queue<int>Q;
    27 struct edge{
    28     int next,to,f;
    29 }e[MAXM];
    30 
    31 inline int getint()
    32 {
    33        int w=0,q=0;
    34        char c=getchar();
    35        while((c<'0' || c>'9') && c!='-') c=getchar();
    36        if (c=='-')  q=1, c=getchar();
    37        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    38        return q ? -w : w;
    39 }
    40 
    41 inline void link(int x,int y,int z){
    42     e[++ecnt].next=first[x]; first[x]=ecnt; e[ecnt].to=y; e[ecnt].f=z;
    43     e[++ecnt].next=first[y]; first[y]=ecnt; e[ecnt].to=x; e[ecnt].f=0;
    44 }
    45 
    46 inline bool bfs(){
    47     while(!Q.empty()) Q.pop();
    48     for(int i=1;i<=T;i++) deep[i]=0;
    49     Q.push(S); deep[S]=1;
    50     while(!Q.empty()) {
    51     int u=Q.front(); Q.pop();
    52     for(int i=first[u];i;i=e[i].next) {
    53         int v=e[i].to;
    54         if(e[i].f && !deep[v]) deep[v]=deep[u]+1,Q.push(v);
    55     }
    56     }
    57     if(deep[T]!=0) return true;
    58     return false;
    59 }
    60 
    61 inline int Dinic(int x,int remain){
    62     if(remain==0 || x==T) return remain;
    63     int f,flow=0;
    64     for(int i=first[x];i;i=e[i].next) {
    65     int v=e[i].to;
    66     if(e[i].f && deep[v]==deep[x]+1){
    67         f=Dinic(v,min(remain,e[i].f));
    68         if(f){
    69         flow+=f; e[i].f-=f; e[i^1].f+=f;
    70         remain-=f; if(remain==0) return flow;
    71         } else deep[v]=-1;
    72     }
    73     }
    74     return flow;
    75 }
    76 
    77 inline void work(){
    78     m=getint(); n=getint();
    79     for(int i=1;i<=m;i++) for(int j=1;j<=n;j++)   a[i][j]=getint(),sum+=a[i][j];
    80     S=m*n+1;T=S+1; ecnt=1;
    81     for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if((i+j)%2==0) link(S,(i-1)*n+j,a[i][j]); else link((i-1)*n+j,T,a[i][j]);//黑白染色
    82     for(int i=1;i<=m;i++) 
    83     for(int j=1;j<=n;j++){
    84         if((i+j)%2) continue;
    85         if(i!=1) link((i-1)*n+j,(i-2)*n+j,inf);     
    86         if(j!=1) link((i-1)*n+j,(i-1)*n+j-1,inf);
    87         if(j!=n) link((i-1)*n+j,(i-1)*n+j+1,inf);
    88         if(i!=m) link((i-1)*n+j,i*n+j,inf);
    89     }
    90     while(bfs()) ans+=Dinic(S,inf);
    91     printf("%d",sum-ans);
    92 }
    93 
    94 int main()
    95 {
    96   work();
    97   return 0;
    98 }
  • 相关阅读:
    webkit v8 chromium blink chrome 的关系
    webkit 系列
    工具使用过程中遇到问题
    ElasticSearch实战笔记
    办理北京市居住证需要哪些资料
    办理北京市居住证需要哪些资料
    MongoDB 笔记
    Javascript问题集锦
    sqlserver2016 management tool v18
    PostMan测试Web Service
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5756751.html
Copyright © 2020-2023  润新知