【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 ...
随机推荐
- python爬虫随笔-scrapy框架(1)——scrapy框架的安装和结构介绍
scrapy框架简介 Scrapy,Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试 ...
- 小谈UAT(验收测试)
验收测试人员的测试任务: 1.验收人员是提出需求的人员,所以对需求最为熟悉,最主要测试功能的遗漏或者多余2.系统测试人员重点在测试功能的正确性和非功能的符合性,当然也希望验收人员测试功能的正确性3.因 ...
- itoa函数实现
1. 整数字符转化为字符串数 // 将整数转换成字符串数,不用函数itoa // 思路:采用加'0',然后在逆序的方法 #include <iostream> using nam ...
- centos7下安装python3.6
一.wget 官网下载到本地 进入家目录: cd ~ wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz下载到本地 解压移动到/ ...
- Nagios 系统监控
Nagios 系统监控 Nagios 是一款免费的开源 IT 基础设施监控系统,功能强大,灵活性强,能有效监控 Windows.Linux.VMware 和 Unix 主机状态,交换机.路由器等网络设 ...
- Linux系统mysql使用(二)
一.查看某数据库的表 # 假设此时数据库名为hiveuse hive; show tables;
- SQL not exist out join
sql中exists,not exists的用法 - 飞翔-方向 积累 沉淀 - 博客园http://www.cnblogs.com/mytechblog/articles/2105785.html ...
- mysql 无法退出sql命令行编辑
mysql 无法退出sql命令行编辑 | ANBOBhttp://www.anbob.com/archives/579.html mysql 无法退出sql命令行编辑 - 码农甲乙丙 - CSDN博客 ...
- [转帖]浅谈程序中的text段、data段和bss段
作者:百问科技链接:https://zhuanlan.zhihu.com/p/28659560来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一般情况,一个程序本质上都 ...
- MQ4入门篇(一)
写一个下单功能,和一个平仓功能: 下单: 1:下单使用到的函 int OrderSend(string symbol, int cmd, double volume, double price, in ...