题目大意:有一个$n\times m$的矩阵,矩阵的每个位置上有一个同学,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。求一个方案,使得全班的喜悦值总和最大。

数据范围:$n,m≤100$,权值$≤5000$。
此题直接最小割,对于一对相邻的同学$(A,B)$,设$L_A$表示$A$同学选理的喜悦值,$W_A$表示$A$同学选文的喜悦值(前面说的两种情况$B$同理),设$L$为两个人都选理的额外收获喜悦值,$W$为两个人都选文的额外收获喜悦值,则有:
$S->A$ ,权值为:$L_A+\frac{1}{2}L$
$A->T$ ,权值为:$W_A+\frac{1}{2}W$
$S->A$ ,权值为:$L_A+\frac{1}{2}L$
$A->T$ ,权值为:$W_A+\frac{1}{2}W$
$A<->B$,权值为:$\frac{1}{2}(L+W)$
当点数变多的时候,情况会有所不同,基于这个思路简单变形下就好了
建完图后跑最大流就行了
B站上的数据比较水,我们OJ上的数据加强了必须加上一个特殊的剪枝才能过(新姿势get)

 #include<bits/stdc++.h>
#define M 300005
#define N 105
#define INF 1145141919
#define F(_x,_y) for(int i=1;i<=(_x);i++) for(int j=1;j<=(_y);j++)
using namespace std; struct edge{int u,v,next;}e[M]={}; int head[M]={},use=;
void add(int x,int y,int z){e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use++;}
void Add(int x,int y,int z){add(x,y,z); add(y,x,);}
int n,m,a[N][N]={},b[N][N]={},sum=,id[N][N]={},d[N][N]={},r[N][N]={},cnt=;
int S,T,vis[M]={}; queue<int> q; bool bfs(){
q.push(S); memset(vis,,(cnt+)<<); vis[S]=;
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=head[u];~i;i=e[i].next)
if(e[i].v&&vis[e[i].u]==){
vis[e[i].u]=vis[u]+;
q.push(e[i].u);
}
}
return vis[T];
}
int dfs(int x,int flow){
if(x==T) return flow; int sum=;
for(int i=head[x];~i;i=e[i].next)
if(e[i].v&&vis[e[i].u]==vis[x]+){
int k=dfs(e[i].u,min(flow,e[i].v));
e[i].v-=k; e[i^].v+=k;
sum+=k; flow-=k;
if(flow==) return sum;
}
if(sum==) vis[x]=-;
return sum;
}
int dinic(){
int res=;
while(bfs())
res+=dfs(S,INF);
return res;
} int main(){
//freopen("in.txt","r",stdin);
memset(head,-,sizeof(head));
S=; T=; cnt=;
scanf("%d%d",&n,&m);
F(n,m) id[i][j]=++cnt;
F(n,m) scanf("%d",&a[i][j]),sum+=a[i][j],a[i][j]<<=;
F(n,m) scanf("%d",&b[i][j]),sum+=b[i][j],b[i][j]<<=;
F(n-,m){
int x; scanf("%d",&x);
a[i][j]+=x; a[i+][j]+=x; sum+=x; d[i][j]+=x;
}
F(n-,m){
int x; scanf("%d",&x);
b[i][j]+=x; b[i+][j]+=x; sum+=x; d[i][j]+=x;
}
F(n,m-){
int x; scanf("%d",&x);
a[i][j]+=x; a[i][j+]+=x; sum+=x; r[i][j]+=x;
}
F(n,m-){
int x; scanf("%d",&x);
b[i][j]+=x; b[i][j+]+=x; sum+=x; r[i][j]+=x;
}
F(n,m){
Add(S,id[i][j],a[i][j]);
Add(id[i][j],T,b[i][j]);
}
F(n,m-){
add(id[i][j],id[i][j+],r[i][j]);
add(id[i][j+],id[i][j],r[i][j]);
}
F(n-,m){
add(id[i][j],id[i+][j],d[i][j]);
add(id[i+][j],id[i][j],d[i][j]);
}
int hh=dinic();
hh>>=;
cout<<sum-hh<<endl;
}

【BZOJ2127】happiness 最小割的更多相关文章

  1. [bzoj2127]happiness——最小割

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

  2. [置顶] [BZOJ]2127: happiness 最小割

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

  3. [BZOJ2127]happiness-[网络流-最小割]

    Description 传送门 Solution 按照最小割的思路考虑. 根据题意,当两个人都选文(理),需要砍掉两个人都选理(文)的加成:如果两个人选的不一样,就要都砍掉. 这是一个网络流建模的套路 ...

  4. [国家集训队]happiness 最小割 BZOJ 2127

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

  5. BZOJ 2127 / Luogu P1646 [国家集训队]happiness (最小割)

    题面 BZOJ传送门 Luogu传送门 分析 这道题又出现了二元关系,于是我们只需要解方程确定怎么连边就行了 假设跟SSS分在一块是选文科,跟TTT分在一块是选理科,先加上所有的收益,再来考虑如何让需 ...

  6. luogu P1646 [国家集训队]happiness (最小割)

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

  7. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  8. BZOJ 2127: happiness(最小割解决集合划分)

    Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2350  Solved: 1138[Submit][Status][Discuss] Descript ...

  9. 【BZOJ2127】happiness(最小割)

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

随机推荐

  1. 转录组差异表达分析工具Ballgown

    Ballgown是分析转录组差异表达的R包. 软件安装: 运行R, source(“http://bioconductor.org/biocLite.R”) biocLite(“ballgown”) ...

  2. 2018.09.21 atcoder An Invisible Hand(贪心)

    传送门 简单贪心啊. 这题显然跟t并没有关系,取差量最大的几组买入卖出就行了. 于是我们统计一下有几组差量是最大的就行了. 代码: #include<bits/stdc++.h> #def ...

  3. C语言学生管理系统源码分享

    大家好 我就是如假包换的...陈玲 自从运营了C语言程序设计微信公众号 很多粉丝都给我备注 ...奇葩 实在是不敢当 也被人开始叫玲玲姐 我知道 很多人都想看我出境 我本人也有 年多的舞台演讲训练 实 ...

  4. 函数作用域和块级作用域--你不知道的JavaScript

    et和const在{}内声明都会变为外部不能访问的值,但是const声明的是常量,也不能修改 函数是 JavaScript 中最常见的作用域单元.本质上,声明在一个函数内部的变量或函数会在所处的作用域 ...

  5. node.js初步总结

    一:先上一段代码 process.argv.forEach(function (val, index, array) {    console.log(index + ":" + ...

  6. day3之装饰器

    1.什么是装饰器? #在不改变原函数的调用的情况下,为原函数增加一些额外的功能,打印日志,执行时间,登录认证 2.装饰器的形成过程 # 需求写一个函数测试另一个函数的执行效率 最初的实现方式,但是改变 ...

  7. C++中的数组问题

    C++中的数组问题 1. 数组赋值与初始化 (1)直接初始化: ]={,,}: (2)遍历访问初始化: ;i< ;i++) //直接读入,或者用别的数组,以及别的(i+1)等. (3)内存操作函 ...

  8. hdu 4981

    中位数是否大于平均数 水题 #include <cstdio> #include <cstdlib> #include <cmath> #include <c ...

  9. delphi API: SetWindowPos改变窗口的位置与状态

    SetWindowPos 函数功能:该函数改变一个子窗口,弹出式窗口式顶层窗口的尺寸,位置和Z序.子窗口,弹出式窗口,及顶层窗口根据它们在屏幕上出现的顺序排序.顶层窗口设置的级别最高,并且被设置为Z序 ...

  10. mssql内存表

    自MSSQL2014开始引入内存表. 怎样创建内存表: USE testGO ALTER DATABASE testADD FILEGROUP fg_test CONTAINS MEMORY_OPTI ...