首页 > 代码库 > BZOJ 2127: happiness [最小割]

BZOJ 2127: happiness [最小割]

2127: happiness

Time Limit: 51 Sec  Memory Limit: 259 MB
Submit: 1815  Solved: 878
[Submit][Status][Discuss]

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
【样例说明】
两人都选理,则获得100+110+1000的喜悦值。
【数据规模】
对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数

本题和上一题很相似,可以用相同的做法
但是本题可以优化
相邻两个人具有经典的棋盘黑白染色的特征,虽然本题貌似与二分图无关,这是句废话
能不能在一人一点的基础上直接处理出神秘加成
放弃文同时也是放弃了 神秘加成_文/2
两个人都放弃文就成功的放弃了整个 神秘加成_文
理同理
但是一人选文一人选理两个神秘加成都不能要啊,但这样每个神秘加成只放弃了1/2
那就再加两条边,链接相邻两个人,容量为(神秘加成_文+神秘加成_理)/2,割的时候一文一理时必定割去这条两条边之一
 
提示:
那两条边可以直接加无向边
注意:
煞笔Candy?数组开成[10005][10005] bzoj不是T就是M
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int N=1e4+5,M=1e5+5,INF=1e9;inline int read(){    char c=getchar();int x=0,f=1;    while(c<0||c>9){if(c==-)f=-1; c=getchar();}    while(c>=0&&c<=9){x=x*10+c-0; c=getchar();}    return x*f;}int n,m,num,s,t,a[105][105],b[105][105],c,f[105][105],g[105][105],sum;struct edge{    int v,c,f,ne;}e[M<<1];int cnt,h[N];inline void ins(int u,int v,int c){    cnt++;    e[cnt].v=v;e[cnt].c=c;e[cnt].f=0;e[cnt].ne=h[u];h[u]=cnt;    cnt++;    e[cnt].v=u;e[cnt].c=0;e[cnt].f=0;e[cnt].ne=h[v];h[v]=cnt;}inline void ins2(int u,int v,int c){    cnt++;    e[cnt].v=v;e[cnt].c=c;e[cnt].f=0;e[cnt].ne=h[u];h[u]=cnt;    cnt++;    e[cnt].v=u;e[cnt].c=c;e[cnt].f=0;e[cnt].ne=h[v];h[v]=cnt;}int q[N],head,tail,vis[N],d[N];bool bfs(){    memset(vis,0,sizeof(vis));    memset(d,0,sizeof(d));    head=tail=1;    d[s]=0;vis[s]=1;    q[tail++]=s;    while(head!=tail){        int u=q[head++];        for(int i=h[u];i;i=e[i].ne){            int v=e[i].v;            if(!vis[v]&&e[i].c>e[i].f){                vis[v]=1;                d[v]=d[u]+1;                q[tail++]=v;                if(v==t) return true;            }        }    }    return false;}int cur[N];int dfs(int u,int a){    if(u==t||a==0) return a;    int flow=0,f;    for(int &i=cur[u];i;i=e[i].ne){        int v=e[i].v;        if(d[v]==d[u]+1&&(f=dfs(v,min(a,e[i].c-e[i].f)))>0){            flow+=f;            e[i].f+=f;            e[((i-1)^1)+1].f-=f;            a-=f;            if(a==0) break;        }    }    return flow;}int dinic(){    int flow=0;    while(bfs()){        for(int i=s;i<=t;i++) cur[i]=h[i];        flow+=dfs(s,INF);    }    return flow;}inline int id(int i,int j){return (i-1)*m+j;}int main(){    //freopen("in.txt","r",stdin);    n=read();m=read();    s=0;t=n*m+1;    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read()<<1,sum+=a[i][j]>>1;    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) b[i][j]=read()<<1,sum+=b[i][j]>>1;    for(int i=1;i<=n-1;i++) for(int j=1;j<=m;j++){        c=read();a[i][j]+=c;a[i+1][j]+=c;sum+=c;        f[i][j]+=c;        //ins2(id(i,j),id(i+1,j),c);    }    for(int i=1;i<=n-1;i++) for(int j=1;j<=m;j++){        c=read();b[i][j]+=c;b[i+1][j]+=c;sum+=c;        f[i][j]+=c;        //ins2(id(i,j),id(i+1,j),c);    }    for(int i=1;i<=n;i++) for(int j=1;j<=m-1;j++){        c=read();a[i][j]+=c;a[i][j+1]+=c;sum+=c;        g[i][j]+=c;        //ins2(id(i,j),id(i,j+1),c);    }    for(int i=1;i<=n;i++) for(int j=1;j<=m-1;j++){        c=read();b[i][j]+=c;b[i][j+1]+=c;sum+=c;        g[i][j]+=c;        //ins2(id(i,j),id(i,j+1),c);    }    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){        ins(s,id(i,j),a[i][j]);        ins(id(i,j),t,b[i][j]);        ins2(id(i,j),id(i+1,j),f[i][j]);        ins2(id(i,j),id(i,j+1),g[i][j]);    }    int ans=dinic();    printf("%d",sum-(ans>>1));}

 

 
 
 

BZOJ 2127: happiness [最小割]