【BZOJ2127】happiness 网络流
题目描述
有\(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 网络流的更多相关文章
- 【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(最小割)
[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 ...
随机推荐
- list tuple
----------------------------善始者善终,笑到最后的,才是最good的.--------------------------------------------------- ...
- 1003: [ZJOI2006]物流运输 = DP+SBFA
题意就是告诉你有n个点,e条边,m天,每天都会从起点到终点走一次最短路,但是有些点在某些时间段是不可走的,因此在某些天需要改变路径,每次改变路径的成本是K,总成本=n天运输路线长度之和+K*改变运输路 ...
- centos7 安装phpmyadmin
1.先安装epel,不然安装pgpmyadmin时会出现找不到包. yum install epel-release rpm -ivh http://rpms.famillecollet.com/en ...
- iOS开发造轮子 | 通用占位图
https://www.jianshu.com/p/beca3ac24031 实际运用场景: 没网时的提示view,tableView或collectionView没内容时的展示view,以及其它特殊 ...
- jmeter高并发设计方案(转)
高并发设计方案二(秒杀架构) 优化方向: (1)将请求尽量拦截在系统上游(不要让锁冲突落到数据库上去).传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超 ...
- ios不触发事件也能播放音频
ios不触发事件也能播放音频. 首先界面初始化预加载一个没有声音的音频,代码如下: html: js: $(function(){ $("#start_audio")[0].pla ...
- h5 文件下载
一.a 标签 移动端不支持 onDownFile= (url, filename) => { const downUrl = `http://10.1.109.123:19092/down/to ...
- react的项目坑
首先在构造页面时 应该将页面的结构分析好. 在处理数据异步时 将数据结构进行完全的简单结构化. 使用redux时 注意返回的数据是深拷贝还是浅拷贝 否则会产生 数组不为空但是没有值的问题 使用自制数据 ...
- [转帖]批处理-For详解
批处理-For详解 https://www.cnblogs.com/DswCnblog/p/5435300.html for 循环的写法 感觉非常好. 今天下午的时候简单测试了下. 多学习提高 非常重 ...
- springmvc配置文件
1 springMVC的配置文件路径问题 https://www.cnblogs.com/ysloong/p/6071450.html