【bzoj2127】happiness 最大流
happiness
Time Limit: 51 Sec Memory Limit: 259 MB
Submit: 2579 Solved: 1245
[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 1
100 110
1
1000
Sample Output
【样例说明】
两人都选理,则获得100+110+1000的喜悦值。
【数据规模】
对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数
HINT
和文理分科差不多
利用最小割考虑。
对于原图中所有相邻的两个人A,B,我们建边:
s->A:cost[A文]+c[文][A][B]/2,s->B:cost[B文]+c[文][A][B]/2;
A->t:cost[A理]+c[理][A][B]/2,B->t:costB[理]+c[理][A][B]/2;
A<–>B:c[文][A][B]/2+c[理][A][B]/2
这样会出现两种割,分别对应两种相同,一种选文一种选理。
#include<iostream>
#include<cstring>
#include<cstdio>
#define T 10001
#define inf 0x7fffffff
#define FOR for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
#define rep(x,y) for(int i=1;i<=x;i++)for(int j=1;j<=y;j++)
#define ll long long
using namespace std;
int n,m,ans,tot,cnt=,head[],h[];
int a[][],b[][],color[][],mark[][];
int xx[]={,,,-},yy[]={,-,,};
struct data{int to,next,v;}e[];
void ins(int u,int v,int w)
{cnt++;e[cnt].to=v;e[cnt].v=w;e[cnt].next=head[u];head[u]=cnt;}
void insert(int u,int v,int w)
{ins(u,v,w);ins(v,u,);}
void ins2(int u,int v,int w)
{ins(u,v,w);ins(v,u,w);}
bool bfs()
{
int q[],t=,w=,i,now;
memset(h,-,sizeof(h));
q[]=h[]=;
while(t!=w)
{
now=q[t];t++;if(t==)t=;
for(i=head[now];i;i=e[i].next)
{
if(e[i].v&&h[e[i].to]<)
{h[e[i].to]=h[now]+;q[w++]=e[i].to;if(w==)w=;}
}
}
if(h[T]==-)return ;return ;
}
int dfs(int x,int f)
{
if(x==T)return f;
int w,used=;
for(int i=head[x];i;i=e[i].next)
{
if(e[i].v&&h[e[i].to]==h[x]+)
{
w=f-used;
w=dfs(e[i].to,min(w,e[i].v));
e[i].v-=w;e[i^].v+=w;
used+=w;if(used==f)return f;
}
}
if(!used)h[x]=-;
return used;
}
void dinic(){while(bfs())ans+=dfs(,inf);}
void build()
{
int x;
rep(n-,m)
{
scanf("%d",&x);tot+=x;
a[i][j]+=x;a[i+][j]+=x;
ins2(mark[i][j],mark[i+][j],x);
}
rep(n-,m)
{
scanf("%d",&x);tot+=x;
b[i][j]+=x;b[i+][j]+=x;
ins2(mark[i][j],mark[i+][j],x);
}
rep(n,m-)
{
scanf("%d",&x);tot+=x;
a[i][j]+=x;a[i][j+]+=x;
ins2(mark[i][j],mark[i][j+],x);
}
rep(n,m-)
{
scanf("%d",&x);tot+=x;
b[i][j]+=x;b[i][j+]+=x;
ins2(mark[i][j],mark[i][j+],x);
}
FOR{
insert(,mark[i][j],a[i][j]);
insert(mark[i][j],T,b[i][j]);
}
}
int main()
{
scanf("%d%d",&n,&m);
FOR scanf("%d",&a[i][j]),tot+=a[i][j],a[i][j]<<=;
FOR scanf("%d",&b[i][j]),tot+=b[i][j],b[i][j]<<=;
FOR mark[i][j]=(i-)*m+j;
build();dinic();
printf("%d",tot-(ans>>));
}
最新文章
- OC----面向对象
- Sqlite学习笔记(一)&;&;编译安装
- css默认值汇总
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- calico docker 应用实例
- ios clang: error: linker command failed with exit code 1 (use -v to see invocation)解决方法
- Java 静态类 static
- 关于matlab矩阵卷积conv2和傅里叶变换求卷积ifft2的关系
- Linux nfs+autofs 环境搭建
- oracle备份与还原(导入导出)
- /etc/services保存了服务、端口、协议
- hdu_1010_Tempter of the Bone_dfs
- 数据库 -->; SQL 和 NoSQL 的区别
- 2017年Kali Linux更新源
- MongoDB中文档操作(二)
- Vivado如何使用命令行创建工程
- Java(原码、反码、补码和计算机存储格式)
- Redis 4.0.2.3 for Windows (alpha) 下载地址
- css居中小技巧
- 清除ul li里面的浮动并让ul自适应高度的一个好办法