• [bzoj1475]方格取数


    将原图黑白染色,然后白点放左边,黑点放右边,原点向白点连点权的边,汇点向黑点连点权的边,白点向相邻黑点流inf的边,求最小割,用总权值减掉最小割即可。这样每相邻两个点一定有一个点的边被割掉,最小割就是最小的去掉的点,剩下的就是最大值了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1005
     4 #define id (i-1)*n+j
     5 #define inf 0x3f3f3f3f
     6 struct ji{
     7     int nex,to,len;
     8 }edge[N*10];
     9 queue<int>q;
    10 int E,n,k,ans,a[N],head[N],work[N],d[N];
    11 void add(int x,int y,int z){
    12     edge[E].nex=head[x];
    13     edge[E].to=y;
    14     edge[E].len=z;
    15     head[x]=E++;
    16     if (E&1)add(y,x,0);
    17 }
    18 bool bfs(){
    19     memset(d,-1,sizeof(d));
    20     q.push(0);
    21     d[0]=0;
    22     while (!q.empty()){
    23         int k=q.front();
    24         q.pop();
    25         for(int i=head[k];i!=-1;i=edge[i].nex)
    26             if ((edge[i].len)&&(d[edge[i].to]<0)){
    27                 d[edge[i].to]=d[k]+1;
    28                 q.push(edge[i].to);
    29             }
    30     }
    31     return d[n]>=0;
    32 }
    33 int dfs(int k,int s){
    34     if (k==n)return s;
    35     int p;
    36     for(int &i=work[k];i!=-1;i=edge[i].nex)
    37         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
    38             p=dfs(edge[i].to,min(s,edge[i].len));
    39             if (p){
    40                 edge[i].len-=p;
    41                 edge[i^1].len+=p;
    42                 return p;
    43             }
    44         }
    45     return 0;
    46 }
    47 int dinic(){
    48     int k,ans=0;
    49     while (bfs()){
    50         memcpy(work,head,sizeof(head));
    51         while (k=dfs(0,inf))ans+=k;
    52     }
    53     return ans;
    54 }
    55 int main(){
    56     scanf("%d",&n);
    57     memset(head,-1,sizeof(head));
    58     for(int i=1;i<=n;i++)
    59         for(int j=1;j<=n;j++){
    60             scanf("%d",&k);
    61             ans+=k;
    62             if ((i+j)&1){
    63                 add(0,id,k);
    64                 if (j>1)add(id,id-1,inf);
    65                 if (j<n)add(id,id+1,inf);
    66                 if (i>1)add(id,id-n,inf);
    67                 if (i<n)add(id,id+n,inf);
    68             }
    69             else add(id,n*n+1,k);
    70         }
    71     n=n*n+1;
    72     printf("%d",ans-dinic());
    73 }
    View Code
  • 相关阅读:
    Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2) E. The Supersonic Rocket
    Codeforces Round #500 (Div. 2) D
    AtCoder Grand Contest 026 D
    Codeforces Round #495 (Div. 2) Sonya and Matrix
    AtCoder Regular Contest 100 E
    1013 数素数
    1010 一元多项式求导(用while接收输入)
    1009 说反话(字符串、栈)
    L2-006 树的遍历 (后序中序求层序)
    L2-004 这是二叉搜索树吗?
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249600.html
Copyright © 2020-2023  润新知