题目描述

  有\(n\times m\)个人,排成一个\(n\times m\)的矩阵。每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。问全班喜悦值的和最大是多少。

  \(n,m\leq 100\)

题解

  先把问题简化,考虑只有两个人,甲选文科的喜悦值为\(a\),甲选理科的喜悦值为\(b\),乙选文科的喜悦值为\(c\),乙选理科的喜悦值为\(d\),两人同时选文科的喜悦值为\(e\),两人同时选理科的喜悦值为\(f\)。

  两个人同时选文或同时选理会有额外喜悦值,这并不太好处理。考虑转化一下。先把两人选文的喜悦值\(a,c\)加上两人同时选文科的喜悦值的一半\(\frac{e}{2}\)。如果只有一人选(即两人选的不同),那么就要减掉\(\frac{e}{2}\)。理科同理。

  这样就是一个网络流的标准模型了。

  最后拿\(a+b+c+d+e+f\)减掉最小割就是答案。

  \(e,f\)有可能是奇数,可以把所有边的容量\(\times 2\),最后再除回来。

  可以得到以下的网络:

  

  多个人的情况和两个人的情况类似,合在一起处理即可。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
#include<queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return s;
}
int upmin(int &a,int b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(int &a,int b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
int v[1000010];
int w[1000010];
int t[1000010];
int h[10010];
int cnt=0;
void add(int x,int y,int z)
{
cnt++;
v[cnt]=y;
w[cnt]=z;
t[cnt]=h[x];
h[x]=cnt;
}
int S,T;
int d[10010];
int e[10010];
int cur[10010];
int num;
int op(int x)
{
return ((x-1)^1)+1;
}
queue<int> q;
void bfs()
{
memset(d,-1,sizeof d);
memcpy(cur,h,sizeof h);
q.push(T);
d[T]=0;
int i,x;
while(!q.empty())
{
x=q.front();
q.pop();
e[d[x]]++;
for(i=h[x];i;i=t[i])
if(w[op(i)]&&d[v[i]]==-1)
{
d[v[i]]=d[x]+1;
q.push(v[i]);
}
}
}
int dfs(int x,int flow)
{
if(x==T)
return flow;
int s=0,c;
int &i=cur[x];
for(;i;i=t[i])
if(d[v[i]]==d[x]-1&&w[i])
{
c=dfs(v[i],min(flow,w[i]));
s+=c;
flow-=c;
w[i]-=c;
w[op(i)]+=c;
if(!flow)
return s;
}
e[d[x]]--;
if(!e[d[x]])
d[S]=num;
e[++d[x]]++;
cur[x]=h[x];
return s;
}
int maxflow()
{
bfs();
int ans=0;
while(d[S]<=num-1)
ans+=dfs(S,0x7fffffff);
return ans;
}
int m1[110][110];
int m2[110][110];
int m3[110][110];
int m4[110][110];
int m5[110][110];
int m6[110][110];
int n,m;
int id(int x,int y)
{
return (x-1)*m+y;
}
int a1[110][110];
int a2[110][110];
int a3[110][110];
int a4[110][110];
int main()
{
open("bzoj2127");
scanf("%d%d",&n,&m);
int i,j;
int sum=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&m1[i][j]);
sum+=2*m1[i][j];
a1[i][j]+=2*m1[i][j];
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&m2[i][j]);
sum+=2*m2[i][j];
a2[i][j]+=2*m2[i][j];
}
for(i=1;i<n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&m3[i][j]);
sum+=2*m3[i][j];
a1[i][j]+=m3[i][j];
a1[i+1][j]+=m3[i][j];
a3[i][j]+=m3[i][j];
}
for(i=1;i<n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&m4[i][j]);
sum+=2*m4[i][j];
a2[i][j]+=m4[i][j];
a2[i+1][j]+=m4[i][j];
a3[i][j]+=m4[i][j];
}
for(i=1;i<=n;i++)
for(j=1;j<m;j++)
{
scanf("%d",&m5[i][j]);
sum+=2*m5[i][j];
a1[i][j]+=m5[i][j];
a1[i][j+1]+=m5[i][j];
a4[i][j]+=m5[i][j];
}
for(i=1;i<=n;i++)
for(j=1;j<m;j++)
{
scanf("%d",&m6[i][j]);
sum+=2*m6[i][j];
a2[i][j]+=m6[i][j];
a2[i][j+1]+=m6[i][j];
a4[i][j]+=m6[i][j];
}
num=n*m+2;
S=n*m+1;
T=n*m+2;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
add(S,id(i,j),a1[i][j]);
add(id(i,j),S,0);
add(id(i,j),T,a2[i][j]);
add(T,id(i,j),0);
}
for(i=1;i<n;i++)
for(j=1;j<=m;j++)
{
add(id(i,j),id(i+1,j),a3[i][j]);
add(id(i+1,j),id(i,j),a3[i][j]);
}
for(i=1;i<=n;i++)
for(j=1;j<m;j++)
{
add(id(i,j),id(i,j+1),a4[i][j]);
add(id(i,j+1),id(i,j),a4[i][j]);
}
int ans=maxflow();
ans=sum-ans;
ans>>=1;
printf("%d\n",ans);
return 0;
}

【BZOJ2127】happiness 网络流的更多相关文章

  1. 【bzoj2127】happiness 网络流最小割

    题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...

  2. bzoj2127: happiness(双倍经验最小割)

    2127: happiness 题目:传送门 题解: 双倍经验美滋滋~ 请看蒟蒻以前写的渣题解...bzoj3894 表示做完自己就最小割了... 代码(直接改的...菜啊): #include< ...

  3. bzoj2127: happiness

    Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友 ...

  4. [bzoj2127]happiness——最小割

    这个题太恶心了...并不想继续做了... 本代码在bzoj上TLE! 大致说一下思路: 建立ST,首先由S连边(S,u,a)a代表学文的分数,连向T(u,T,b)b表示学理的分数,这样构造出了两个人独 ...

  5. BZOJ 2127 happiness ——网络流

    [题目分析] 基本上是第一次真正的使用最小割的模型. 同时加上一个数然后最后再减去是处理负数的一种方法. 设立出来最小割的模型然后解方程是一件很重要的事情,建议取一个相对来说比较简单的值带入求解. 这 ...

  6. 【BZOJ2127】happiness(网络流)

    点此看题面 大致题意: 每个人只能在文科与理科中选择一种.选择每种科目会带来不同的喜悦值,如果相邻的两位同学选择了同一种科目则会带来额外的喜悦值.求喜悦值总和的最大值. 网络流 这道题做法显然是网络流 ...

  7. 【BZOJ2127】happiness(最小割)

    [BZOJ2127]happiness(最小割) 题面 Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了, ...

  8. 文理分科 BZOJ3894 & happiness BZOJ2127

    分析: 最小割(一开始我没看出来...后来经过提点,大致理解...),不选则割的思想. 我们先这样考虑,将和选理相关的和S相连,与选文相关的和T相连,如果没有第二问,那么建图就是简单的S连cnt,cn ...

  9. 【bzoj2127】happiness 最大流

    happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2579  Solved: 1245[Submit][Status][Discuss ...

随机推荐

  1. DOM操作 JS事件 节点增删改查

    --------------------------习惯是社会的巨大的飞轮和最可贵的维护者.——威·詹姆斯 day 49 [value属性操作] <!DOCTYPE html><ht ...

  2. Python全栈开发之路 【第十八篇】:Ajax技术

    Ajax技术 Ajax = 异步 JavaScript 和 XML. Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 1.jQuery的load()方法 jQuery loa ...

  3. 使用insert ignore来避免向数据库重复插入数据

    mysql中 insert ignore 的使用示例如下: INSERT IGNORE INTO `table_name` (`reportid`, `content`) VALUES (‘11111 ...

  4. 使用 Travis CI 实现项目的持续测试反馈

    [篇幅较长,10.15前补充完毕,如希望探索可直接移步Github仓库:https://github.com/SivilTaram/CITest] 在编程课中,我们可以使用成熟的在线评测系统来测试某个 ...

  5. elasticSearch聚合sum查询

    有时需要统计一段时间内,订单的总金额.类似于sql的sum,针对某一字段求和.这就涉及到es的聚合查询,来看看用spring-data-elasticSearch怎么写:   QueryBuilder ...

  6. 容器化-Docker介绍

    导读:本文章对Docker技术进行了介绍,阐述了Docker的技术发展历程.容器与虚拟机的差异.Docker原理.特点.Docker三组件和Docker带来的影响,为我们进一步理解Docker打下基础 ...

  7. 【学习总结】Git学习-参考廖雪峰老师教程二-安装Git

    学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...

  8. [转帖]SAP一句话入门:Sales and Distribution

    SAP一句话入门:Sales and Distribution http://blog.vsharing.com/MilesForce/A616565.html SD是Sales and Distri ...

  9. laravel中如何在模型中自关联?

    https://segmentfault.com/q/1010000007926567 在模型中声明一对多的关系,关联表本身.parent_id对应父记录的id.我在sof中查阅到很多这样的写法: p ...

  10. liunx 运维知识二部分

    Windows下的目录和Linux系统下的目录有什么区别? Windows目录下的文件一般都是分区(C盘,D盘...),C盘下面有什么目录,目录下面还有其他目录加上文件. Linux系统目录结构一切都 ...