bzoj2127: happiness 最小割

来源:互联网 发布:淘宝名词解释大全 编辑:程序博客网 时间:2024/04/30 14:36
Description
高一一班的座位表是个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


第一次写的时候顺利推出公式,然后不知道怎么搞得一直就在wawawaawa tetetetetete

然后我就弃疗了。。。。然后一直在想公式法为什么被叉掉了,壮哉我公式法!!!!!!!!!两个星期后,闲来无事的我在早上一看11点40了,20分钟也没有什么事做,所以就重新推了一下公式。然后就吃饭去了。下午睡醒正当我抱着查一下午的决心去测得时候竟然过了。。。。。再次壮哉我公式法!!!!!人弱没办法,弃疗大法好。。。。

#include <iostream>#include <cstring>#include <algorithm>#include <cmath>#include <cstdio>#include <queue>using namespace std;#define INF 0x3f3f3f3f#define maxn 444444int st,ed,en;struct node{    int v,next,c;}e[maxn];int dis[maxn],first[maxn];int n,m;int q[maxn];bool bfs(){    memset(dis,-1,sizeof(dis));    dis[st]=0;    int tail,head;    tail=head=1;    tail++;    q[tail]=st;    int v,u;    while(head<tail)    {        head++;        u=q[head];        for(int i=first[u];i!=-1;i=e[i].next)        {            v=e[i].v;            if(dis[v]!=-1) continue;            if(e[i].c==0) continue;            dis[v]=dis[u]+1;            tail++;            q[tail]=v;            if(v==ed) return true;        }    }    return false;}int dfs(int x,int mx){    if(x==ed||mx==0) return mx;    int f,flow=0,v,ret=0;    for(int i=first[x];i!=-1;i=e[i].next)    {        v=e[i].v;        if(dis[x]+1!=dis[v]) continue;        if((f=dfs(v,min(mx,e[i].c))))        {            e[i].c-=f;            e[i^1].c+=f;            flow+=f;            ret+=f;            mx-=f;            if(!mx) break;        }    }    if(ret==0) dis[x]=-1;    return flow;}int dinic(){    int tmp=0,maxflow=0;    while(bfs())    {        //for(int i=1;i<=ed;i++) cur[i]=first[i];        while(tmp=dfs(st,INF)) maxflow+=tmp;    }    return maxflow;}void add(int a,int b,int c){    //printf("%d %d %d\n",a,b,c);    e[en].v=b;    e[en].next=first[a];    e[en].c=c;    first[a]=en;    en++;     e[en].v=a;    e[en].next=first[b];    e[en].c=0;    first[b]=en;    en++;}void init(){    en=0;    memset(first,-1,sizeof(first));    st=n*m*5+1;    ed=st+1;}int ans;int getnum(int a,int b,int c){    return (c-1)*(n*m)+m*(a-1)+b;}int main(){    //freopen("happiness3.in","r",stdin);    //freopen("happiness.out","w",stdout);    scanf("%d%d",&n,&m);    init();    int a,b,c;    //xuewen    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            scanf("%d",&a);            ans+=a;            add(st,getnum(i,j,1),a);        }    }    //xueli    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            scanf("%d",&a);            ans+=a;            add(getnum(i,j,1),ed,a);        }    }    /////////////////////////////////////////    //tl xuewen    for(int i=1;i<n;i++)    {        for(int j=1;j<=m;j++)        {            scanf("%d",&a);            ans+=a;            add(st,getnum(i,j,2),a);            add(getnum(i,j,2),getnum(i,j,1),INF);            add(getnum(i,j,2),getnum(i+1,j,1),INF);        }    }    //tl xueli    for(int i=1;i<n;i++)    {        for(int j=1;j<=m;j++)        {            scanf("%d",&a);            ans+=a;            add(getnum(i,j,3),ed,a);            add(getnum(i,j,1),getnum(i,j,3),INF);            add(getnum(i+1,j,1),getnum(i,j,3),INF);        }    }    //tx xuewen    for(int i=1;i<=n;i++)    {        for(int j=1;j<m;j++)        {            scanf("%d",&a);            ans+=a;            add(st,getnum(i,j,4),a);            add(getnum(i,j,4),getnum(i,j,1),INF);            add(getnum(i,j,4),getnum(i,j+1,1),INF);        }    }    //tx xueli    for(int i=1;i<=n;i++)    {        for(int j=1;j<m;j++)        {            scanf("%d",&a);            ans+=a;            add(getnum(i,j,5),ed,a);            add(getnum(i,j,1),getnum(i,j,5),INF);            add(getnum(i,j+1,1),getnum(i,j,5),INF);        }    }    printf("%d\n",ans-dinic());    return 0;}/*2 220 2020 20 10 1010 10 0 010 100 010 10*/


0 0