happiness

happiness

高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。

Input

第一行两个正整数n,m。

接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。

第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。

第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。

第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。

五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。

第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。

Output

输出一个整数,表示喜悦值总和的最大值

Sample Input

1 2

1 1

100 110

1

1000

Sample Output

1210

【样例说明】

两人都选理,则获得\(100+110+1000\)的喜悦值。

【数据规模】

对于100%以内的数据\(,n,m<=100\)所有喜悦值均为小于等于\(5000\)的非负整数

思路:

\(s\)\((i,j)\)连边\(v_文(i,j),\)\((i,j)\)\(t\)连边\(v_理(i,j),\)\(s\)向辅助点\(x\)连边\(v_{同文}((i,j),(i-1,j))\),从\(x\)\((i,j),(i-1,j)\)连边\(inf,\)同理\(,\)向四周\(、\)同文同理建立关系

证明:

先求总贡献\((\sum_{i=1}^mv_{文...}),\)减去最小的非法贡献\((\)最小割\()\)

\(\mathfrak{Talk\ is\ cheap,show\ you\ the\ code.}\)

#include
#include
#include
#include
#include
using namespace std;
# define read read1()
# define Type template
Type inline T read1(){
    T n=0;
    char k;
    bool fl=0;
    do (k=getchar())=='-'&&(fl=1);while('9'0){
                        int to=G.G[i].u;
                        lev[to]=lev[u]+1;
                        q[t++]=to;
                        if(to==T)return 1;
                    }
                }
            }
            return 0;
        }
        double dfs(int u,double f){
            if(u==T)return f;
            double tag=0,c;
            for(int &i=cur[u];i;i=G.G[i].t){
                int to=G.G[i].u;
                if(G.G[i].v>0&&lev[to]==lev[u]+1){
                    c=dfs(to,min(f-tag,G.G[i].v));
                    G.G[i].v-=c;
                    G.G[(i-1^1)+1].v+=c;
                    tag+=c;
                    if(tag==f)return tag; 
                }
            }
            return tag;
        }
        double Dinic(){
            double ans=0;
            while(bfs()){
                for(int i=0;i++^n;)cur[i]=G.f[i];
                ans+=dfs(S,2e9);
            }
            return ans;
        }
    # undef Big
    # undef Big2
};
int n=read,m=read,tot,t,l;
Flow G(n*m*6+10,1,2);
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define f(i,l,r) for(int i=l;i<=r;++i)
int Hash(int x,int y){return (x-1)*m+y;}
int main(){
    //fre("..\\1");
    tot=n*m+2;
    f(i,1,n)f(j,1,m)G.add(1,Hash(i,j)+2,l=read),t+=l;
    f(i,1,n)f(j,1,m)G.add(Hash(i,j)+2,2,l=read),t+=l;
    f(i,1,n-1)f(j,1,m)G.add(1,++tot,l=read),G.add(tot,Hash(i,j)+2,Imax),G.add(tot,Hash(i+1,j)+2,Imax),t+=l;
    f(i,1,n-1)f(j,1,m)G.add(++tot,2,l=read),G.add(Hash(i,j)+2,tot,Imax),G.add(Hash(i+1,j)+2,tot,Imax),t+=l;
    f(i,1,n)f(j,1,m-1)G.add(1,++tot,l=read),G.add(tot,Hash(i,j)+2,Imax),G.add(tot,Hash(i,j+1)+2,Imax),t+=l;
    f(i,1,n)f(j,1,m-1)G.add(++tot,2,l=read),G.add(Hash(i,j)+2,tot,Imax),G.add(Hash(i,j+1)+2,tot,Imax),t+=l;
    printf("%.0f\n",t-G.Dinic());
    return 0;
}

你可能感兴趣的:(happiness)