bzoj 2127 happiness【最小割+dinic】
参考:https://www.cnblogs.com/chenyushuo/p/5144957.html 不得不说这个建图方法真是非常妙啊
假设S点选理,T点选文,a[i][j]为(i,j)选文收益,b[i][j]为(i,j)选理收益,c[i][j]为同时选文收益,d[i][j]为同时选文收益。
那么对于每个点x=(i+1)*m+j,我们连接
\]
\]
对于有利益相关的x,y两点,连接
\]
\]
\]
\]
\]
\]
建完的图:

然后考虑最小割,下面枚举几种情况:
都选文,即割掉了x选理,y选理和(x,y)都选理:

都选理,即割掉了x选文,y选文和(x,y)都选文:

x选文y选理,即割掉了x选理,y选文,(x,y)都选理/+(x,y)都选理/2+(x,y)都选文/2+(x,y)都选文/2,即,割掉x选理,y选文,(x,y)都选理,(x,y)都选文:

y选文x选理,即割掉了x选文,y选理,(x,y)都选理/+(x,y)都选理/2+(x,y)都选文/2+(x,y)都选文/2,即,割掉x选文,y选理,(x,y)都选理,(x,y)都选文:

对于除以2的操作,为避免下取整的误差,我们选择把所有流量都*2,最后再/2。
$ ans=sum(全部收益)- 最小割 $
p.s.用邻接表建图的时候先把每个点选单科的边连上,再练同时选的收益,否则会重
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=105,E=1000005,inf=1e9,P=500005;
int n,m,a[N][N],b[N][N],c[N][N],d[N][N],s,t,sum,cnt=1,h[P],le[N*N];
struct qwe
{
int ne,to,va;
}e[E];
int read()
{
int r=0;
char p=getchar();
while(p<'0'||p>'9')
p=getchar();
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r;
}
void add(int u,int v,int w)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
e[cnt].va=w;
h[u]=cnt;
}
bool bfs()
{
queue<int>q;
memset(le,0,sizeof(le));
le[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();//cout<<u<<"AAAAAAAAAAAA"<<endl;
q.pop();
for(int i=h[u];i;i=e[i].ne)
if(e[i].va&&!le[e[i].to])
{
le[e[i].to]=le[u]+1;
q.push(e[i].to);
}
}
// for(int i=0;i<=5;i++)
// cout<<le[i]<<" ";
return le[t];
}
int dfs(int u,int f)
{//cout<<u<<" "<<f<<endl;
if(u==t)
{
//cout<<"!!";
return f;
}
int used=0;
for(int i=h[u];i;i=e[i].ne)
{
//cout<<u<<" "<<e[i].to<<" "<<e[i].va<<endl;;
if(e[i].va>0&&le[e[i].to]==le[u]+1)
{//cout<<"OK"<<endl;
int w=dfs(e[i].to,min(f-used,e[i].va));
e[i].va-=w;
e[i^1].va+=w;
used+=w;
if(used==f)
return f;
}
}
if(!used)
le[u]=-1;
return used;
}
int dinic()
{
int ans=0;
while(bfs())
ans+=dfs(s,inf);//,cout<<ans<<endl;
return ans;
}
int main()
{
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(),sum+=a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
b[i][j]=read(),sum+=b[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int x=(i-1)*m+j;
add(s,x,b[i][j]<<1);
add(x,s,0);
add(x,t,a[i][j]<<1);
add(t,x,0);
}
for(int i=1;i<n;i++)
for(int j=1;j<=m;j++)
c[i][j]=read(),sum+=c[i][j];
for(int i=1;i<n;i++)
for(int j=1;j<=m;j++)
d[i][j]=read(),sum+=d[i][j];
for(int i=1;i<n;i++)
for(int j=1;j<=m;j++)
{
int x=(i-1)*m+j,y=i*m+j;
add(s,x,d[i][j]);
add(x,s,0);
add(s,y,d[i][j]);
add(y,s,0);
add(x,y,c[i][j]+d[i][j]);
add(y,x,c[i][j]+d[i][j]);
add(x,t,c[i][j]);
add(t,x,0);
add(y,t,c[i][j]);
add(t,y,0);
}
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)
c[i][j]=read(),sum+=c[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)
d[i][j]=read(),sum+=d[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)
{
int x=(i-1)*m+j,y=(i-1)*m+j+1;
add(s,x,d[i][j]);
add(x,s,0);
add(s,y,d[i][j]);
add(y,s,0);
add(x,y,c[i][j]+d[i][j]);
add(y,x,c[i][j]+d[i][j]);
add(x,t,c[i][j]);
add(t,x,0);
add(y,t,c[i][j]);
add(t,y,0);
}
printf("%d\n",sum-(dinic()>>1));
return 0;
}
bzoj 2127 happiness【最小割+dinic】的更多相关文章
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- [置顶] [BZOJ]2127: happiness 最小割
happiness: Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己 ...
- BZOJ 2127: happiness(最小割解决集合划分)
Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 2350 Solved: 1138[Submit][Status][Discuss] Descript ...
- [BZOJ 2127] happiness 【最小割】
题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建 ...
- BZOJ 2127 / Luogu P1646 [国家集训队]happiness (最小割)
题面 BZOJ传送门 Luogu传送门 分析 这道题又出现了二元关系,于是我们只需要解方程确定怎么连边就行了 假设跟SSS分在一块是选文科,跟TTT分在一块是选理科,先加上所有的收益,再来考虑如何让需 ...
- [国家集训队]happiness 最小割 BZOJ 2127
题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...
- bzoj 3144 [Hnoi2013]切糕【最小割+dinic】
都说了是'切'糕所以是最小割咯 建图: 每个点向下一层连容量为这个点的val的边,S向第一层连容量为inf的边,最后一层向T连容量为自身val的边,即割断这条边相当于\( f(i,j) \)选择了当前 ...
- [bzoj2127]happiness——最小割
这个题太恶心了...并不想继续做了... 本代码在bzoj上TLE! 大致说一下思路: 建立ST,首先由S连边(S,u,a)a代表学文的分数,连向T(u,T,b)b表示学理的分数,这样构造出了两个人独 ...
- spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】
因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...
随机推荐
- eclipse默认指定项目的编译器版本
eclipse 提示 @Override must override a superclass method 问题解决 今天新换了一个Eclipse 版本: Build id: 20140224-06 ...
- SQL 视图(Views)
SQL 视图(Views) 视图是可视化的表. 本章讲解如何创建.更新和删除视图. SQL CREATE VIEW 语句 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列 ...
- 搜索学术论文訪问google的能用的几个IP地址
google搜索引擎打不开时的解决的方法,谷歌(google)的IP是多少? google IP镜像. 这里搜集了几个经过測试可用的IP,用来在不能域名訪问google的时候进行訪问 更新一个最新的. ...
- 2016/3/17 Mysq select 数学函数 字符串函数 时间函数 系统信息函数 加密函数
一,数学函数主要用于处理数字,包括整型.浮点数等. ABS(X) 返回x的绝对值 SELECT ABS(-1)--返回1 CEll(X),CEILING(x) 返回大于或等于x的最小整数 SELEC ...
- tcp state
[root@hadoop1 log]# netstatActive Internet connections (w/o servers)Proto Recv-Q Send-Q Local Addres ...
- (ros/moveit)cob_simulation報錯
cob_simulation報錯 依照官網說明 http://wiki.ros.org/cob_bringup_sim 1. git clone https://github.com/ipa320/c ...
- ZFIND_EXIT_BADI
*&---------------------------------------------------------------------* *& Report ZFIND_EX ...
- Error CREATEing SolrCore 'new_core': Unable to create core [new_core] Caused by: Can't find resource 'solrconfig.xml' in classpath or 'D:\solr\solr-7.2.1\server\solr\new_core'
\solr-7.2.1\server\solr\configsets\_default 下的conf 复制到: \solr-7.2.1\server\solr\new_core
- HDU2444 The Accomodation of Students —— 二分图最大匹配
题目链接:https://vjudge.net/problem/HDU-2444 The Accomodation of Students Time Limit: 5000/1000 MS (Java ...
- JavaScript 在浏览器环境中的模块管理
如果需要,请自行复制下或下载列代码清单到本地运行(如果不修改源码,这些文件需要在同一目录 ,并且以下列文件名对应) 我只在Chrome浏览器中调试过(现在也没去处理浏览器兼容方面的问题)1. 代码/ ...