【BZOJ2127】happiness(网络流)
大致题意: 每个人只能在文科与理科中选择一种。选择每种科目会带来不同的喜悦值,如果相邻的两位同学选择了同一种科目则会带来额外的喜悦值。求喜悦值总和的最大值。
网络流
这道题做法显然是网络流。
但是网络流最难的地方就难在建图。
建图
以相邻两点为例,我们可以按照这样的方式建图:

其中,\(a_i\)表示\(i\)选文科的喜悦值,\(b_i\)表示\(i\)选理科的喜悦值,\(c_{i,j}\)表示\(i,j\)同选文科的喜悦值,\(d_{i,j}\)表示\(i,j\)同选理科的喜悦值。
则可以发现,用喜悦值总和\(a_1+b_1+c_{1,2}+d_{1,2}\)减去图中的任意一个割,都恰好对应某种情况的喜悦值:
- \(1,2\)同选文:割去\(1->t,2->t\),得\(sum-(b_1+\frac{d_{1,2}}2)-(b_2+\frac{d_{1,2}}2)=a_1+a_2+c_{1,2}\)。
- \(1,2\)同选理:割去\(s->1,s->2\),得\(sum-(a_1+\frac{c_{1,2}}2)-(a_2+\frac{c_{1,2}}2)=b_1+b_2+d_{1,2}\)。
- \(1\)选文,\(2\)选理:割去\(s->2,1->2,1->t\),得\(sum-(a_2+\frac{c_{1,2}}2)-(\frac{c_{1,2}}2+\frac{d_{1,2}}2)-(b_1+\frac{d_{1,2}}2)=a_1+b_2\)。
- \(1\)选理,\(2\)选文:割去\(s->1,2->1,2->t\),得\(sum-(a_1+\frac{c_{1,2}}2)-(\frac{c_{1,2}}2+\frac{d_{1,2}}2)-(b_2+\frac{d_{1,2}}2)=a_2+b_1\)。
而要使喜悦值最大,就应该用喜悦值总和减去这张图的最小割。
又由于最小割=最大流定理,我们直接求出最大流,然后用喜悦值总和减去即可。
推广到原图中同理。
注意这里涉及到除以\(2\),因此我们在建边时可以将边权都乘\(2\),最后再除即可。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100
#define min(x,y) ((x)<(y)?(x):(y))
#define INF 1e9
using namespace std;
int n,m,a[N+5][N+5],b[N+5][N+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
#undef D
}F;
class Dinic//Dinic跑网络流
{
private:
#define add(x,y,v) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].Cap=v)
static const int Psz=N*N+2,Lsz=(N*N<<2)+(N*N<<3);int ee,lnk[Psz+5],cur[Psz+5],q[Psz+5],dep[Psz+5];
struct edge {int to,nxt,Cap;}e[Lsz+5];
I bool BFS()//BFS找增广路
{
RI i,k,H=1,T=1;memset(dep,0,sizeof(dep)),dep[q[1]=s]=1;W(H<=T&&!dep[t])
for(i=lnk[k=q[H++]];i;i=e[i].nxt) e[i].Cap&&!dep[e[i].to]&&(dep[q[++T]=e[i].to]=dep[k]+1);
return dep[t]?(memcpy(cur,lnk,sizeof(lnk)),true):false;
}
I int DFS(CI x,RI f)//DFS统计流量
{
if(!(x^t)||!f) return f;RI i,t,res=0;
for(i=cur[x];i;i=e[i].nxt)
{
if(cur[x]=i,(dep[x]+1)^dep[e[i].to]||!(t=DFS(e[i].to,min(f,e[i].Cap)))) continue;
if(e[i].Cap-=t,e[((i-1)^1)+1].Cap+=t,res+=t,!(f-=t)) break;
}return !res&&(dep[x]=-1),res;
}
public:
int s,t;I Dinic() {s=1,t=2;}I int P(CI x,CI y) {return (x-1)*m+y+2;}
I void AddOneWayEdge(CI x,CI y,CI v) {add(x,y,v),add(y,x,0);}//建单向边
I void AddTwoWayEdge(CI x,CI y,CI v) {add(x,y,v),add(y,x,v);}//建双向边
I int MaxFlow() {RI res=0;W(BFS()) res+=DFS(s,INF);return res;}//求最大流
}D;
int main()
{
RI i,j,x,ans=0;F.read(n,m);
for(i=1;i<=n;++i) for(j=1;j<=m;++j) F.read(a[i][j]),ans+=a[i][j],a[i][j]<<=1;//读入,更新喜悦值总和,并将其乘2
for(i=1;i<=n;++i) for(j=1;j<=m;++j) F.read(b[i][j]),ans+=b[i][j],b[i][j]<<=1;//读入,更新喜悦值总和,并将其乘2
for(i=1;i^n;++i) for(j=1;j<=m;++j) F.read(x),ans+=x,a[i][j]+=x,a[i+1][j]+=x,D.AddTwoWayEdge(D.P(i,j),D.P(i+1,j),x);//读入,更新喜悦值总和和源点流向这两个节点的流量,然后在这两点间建双向边
for(i=1;i^n;++i) for(j=1;j<=m;++j) F.read(x),ans+=x,b[i][j]+=x,b[i+1][j]+=x,D.AddTwoWayEdge(D.P(i,j),D.P(i+1,j),x);//读入,更新喜悦值总和和这两个节点流向汇点的流量,然后在这两点间建双向边
for(i=1;i<=n;++i) for(j=1;j^m;++j) F.read(x),ans+=x,a[i][j]+=x,a[i][j+1]+=x,D.AddTwoWayEdge(D.P(i,j),D.P(i,j+1),x);//读入,更新喜悦值总和和源点流向这两个节点的流量,然后在这两点间建双向边
for(i=1;i<=n;++i) for(j=1;j^m;++j) F.read(x),ans+=x,b[i][j]+=x,b[i][j+1]+=x,D.AddTwoWayEdge(D.P(i,j),D.P(i,j+1),x);//读入,更新喜悦值总和和这两个节点流向汇点的流量,然后在这两点间建双向边
for(i=1;i<=n;++i) for(j=1;j<=m;++j) D.AddOneWayEdge(D.s,D.P(i,j),a[i][j]),D.AddOneWayEdge(D.P(i,j),D.t,b[i][j]);//建源点流向该节点和该节点流向汇点的单向边
return printf("%d",ans-(D.MaxFlow()>>1)),0;//输出答案
}
【BZOJ2127】happiness(网络流)的更多相关文章
- 【BZOJ2127】happiness 网络流
题目描述 有\(n\times m\)个人,排成一个\(n\times m\)的矩阵.每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一 ...
- 【bzoj2127】happiness 网络流最小割
题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...
- bzoj2127: happiness(双倍经验最小割)
2127: happiness 题目:传送门 题解: 双倍经验美滋滋~ 请看蒟蒻以前写的渣题解...bzoj3894 表示做完自己就最小割了... 代码(直接改的...菜啊): #include< ...
- bzoj2127: happiness
Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友 ...
- [bzoj2127]happiness——最小割
这个题太恶心了...并不想继续做了... 本代码在bzoj上TLE! 大致说一下思路: 建立ST,首先由S连边(S,u,a)a代表学文的分数,连向T(u,T,b)b表示学理的分数,这样构造出了两个人独 ...
- BZOJ 2127 happiness ——网络流
[题目分析] 基本上是第一次真正的使用最小割的模型. 同时加上一个数然后最后再减去是处理负数的一种方法. 设立出来最小割的模型然后解方程是一件很重要的事情,建议取一个相对来说比较简单的值带入求解. 这 ...
- 【BZOJ2127】happiness(最小割)
[BZOJ2127]happiness(最小割) 题面 Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了, ...
- 文理分科 BZOJ3894 & happiness BZOJ2127
分析: 最小割(一开始我没看出来...后来经过提点,大致理解...),不选则割的思想. 我们先这样考虑,将和选理相关的和S相连,与选文相关的和T相连,如果没有第二问,那么建图就是简单的S连cnt,cn ...
- 【bzoj2127】happiness 最大流
happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 2579 Solved: 1245[Submit][Status][Discuss ...
随机推荐
- win10下Anaconda3在虚拟环境python_version=3.5.3 中配置pyspark
1. 序经过了一天的修炼,深深被恶心了,在虚拟环境中配置pyspark花式报错,由于本人实在是不想卸载3.6版的python,所以硬刚了一天,终于摸清了配置方法,并且配置成功,不抱怨了,开讲: 2. ...
- 缓存方案:本地guavaCache, 远程redis?
线程内部缓存:a. 局部变量HashMap, 方法间传递 b. 使用ThreadLocal 本地缓存:单jvm内共享 可以使用(Concurrent)HashMap自己实现,也可以使用GuavaCa ...
- .netcore在linux下使用P/invoke方式调用linux动态库
http://www.mamicode.com/info-detail-2358309.html .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...
- chrome浏览器解决 跨域调试问题
1.关闭chrome浏览器(全部) 我们可以通过使用chrome命令行启动参数来改变chrome浏览器的设置,具体的启动参数说明参考这篇介绍.https://code.google.com/p/xia ...
- SCAU 算法课的题
8594 有重复元素的排列问题(优先做) 时间限制:1000MS 内存限制:1000K提交次数:1610 通过次数:656 题型: 编程题 语言: G++;GCC;VC Description ...
- log4j.properties 日志分析
# 多目的地.自定义样式#设置级别和多个目的地#level 是日志记录的优先级,分为 OFF.FATAL.ERROR.WARN.INFO.DEBUG.ALL或者您定义的级别.#Log4j建议只使用四个 ...
- Gradient Boosting算法简介
最近项目中涉及基于Gradient Boosting Regression 算法拟合时间序列曲线的内容,利用python机器学习包 scikit-learn 中的GradientBoostingReg ...
- 深入理解vertical-align和line-height的关系
vertical-align的百分比值不是相对于字体大小或者其他什么属性计算的,而是相对于line-height计算的.举个简单的例子,如下CSS代码: { line-height: 30px; ve ...
- MVC4 过滤器使用和怎样控制全部action和部分action
MVC中的过滤器分四种分别为:IActionFilter(动作过滤器), IAuthorizationFilter(授权过滤器), IExceptionFilter(异常过滤器), IResultFi ...
- 文件夹选择之FolderBrowserDialog控件
应用程序可能只允许用户选择文佳夹而非文件,例如在播放MP3时,用户可能把所有的MP3放在一个文佳夹内,在添加时,只要选择添加这个文佳夹,将会把在这个文件内的所有MP3添加的播放器里.在这里对播放器来说 ...