BZOJ3894:文理分科(最大流)(同BZoj3438)
文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠
结过)
小P所在的班级要进行文理分科。他的班级可以用一个n*m的矩阵进行
描述,每个格子代表一个同学的座位。每位同学必须从文科和理科中选择
一科。同学们在选择科目的时候会获得一个满意值。满意值按如下的方式
得到:
.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如
果选择理科,将得到science[i][j]的满意值。
.如果第i行第J列的同学选择了文科,并且他相邻(两个格子相邻当且
仅当它们拥有一条相同的边)的同学全部选择了文科,则他会更开
心,所以会增加same_art[i][j]的满意值。
.如果第i行第j列的同学选择了理科,并且他相邻的同学全部选择了理
科,则增加same_science[i]j[]的满意值。
小P想知道,大家应该如何选择,才能使所有人的满意值之和最大。请
告诉他这个最大值。
Input
第一行为两个正整数:n,m
接下来n术m个整数,表示art[i][j];
接下来n术m个整数.表示science[i][j];
接下来n术m个整数,表示same_art[i][j];
Output
输出为一个整数,表示最大的满意值之和
Sample Input Sample Output
题意:给定一个N*M的矩阵,每个格子的人可以学文或者学理,学文和学理各有一个满意度,如果以某人为中心的十字内所有人都学文或者学理都会得到一个额外满意度,求最大满意度之和。
思路:BZOJ上面有很多此类题型,用网络里解决的方案大概有两种。
解法1:直接建图求最大流,源点S为学理,汇点T为学文。然后对于学理的“组合”,加一个点W:由源点S加边指向W,容量为组合的收益;W加边指向组合的成员,容量为inf。 同样的,对于学文的“组合”,加一个点E:由E加边指向汇点T,容量为组合的收益;组合的成员加边指向E,容量为inf。 然后求出最小割。
有:ans=sum-maxflow
解法2:先假设全部学理科,再把边权做差(学理-学文的净收益),再求最大闭合权子图:原点与代价点连接,收益点与汇点连接; 收益和-最大流=最大净收益。 那么现在的基本代价或者收益是ai-bi,。然后破坏集合的代价是c1i,得到集合的收益是c2i。 差不多就酱紫。具体的请去看popoqqq的题解。
体会:解法2更有道理一些,但是解法1更通用,无论“有格外收益的组合”长什么样子,都可以轻松加边,然后求最大流。
解法1的代码:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
const int inf=;
int N,M,S,T,ans,maxflow;
int Laxt[maxn],To[maxn],Next[maxn],cap[maxn],cnt=;
int vd[maxn],dis[maxn];
int xx[]={,,,,-};
int yy[]={,,-,,};
void add(int u,int v,int c)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
cap[cnt]=c;
}
int id(int u,int v){
return (u-)*M+v;
}
int sap(int u,int flow)
{
if(flow==||u==T) return flow;
int tmp,delta=;
for(int i=Laxt[u];i;i=Next[i]){
if(dis[u]==dis[To[i]]+&&cap[i]>){
tmp=sap(To[i],min(cap[i],flow-delta));
delta+=tmp;
cap[i]-=tmp;
cap[i^]+=tmp;
if(delta==flow||dis[S]>T+) return delta;
}
}
vd[dis[u]]--;
if(vd[dis[u]]==) dis[S]=T+;
vd[++dis[u]]++;
return delta;
}
int main()
{
int i,j,k,x; scanf("%d%d",&N,&M);
S=; T=*N*M+;
for(i=;i<=N;i++)
for(j=;j<=M;j++){
scanf("%d",&x); ans+=x;
add(S,id(i,j),x); add(id(i,j),S,);
}
for(i=;i<=N;i++)
for(j=;j<=M;j++){
scanf("%d",&x); ans+=x;
add(id(i,j),T,x); add(T,id(i,j),);
}
for(i=;i<=N;i++)
for(j=;j<=M;j++){
scanf("%d",&x); ans+=x;
add(S,N*M+id(i,j),x); add(N*M+id(i,j),S,);
for(k=;k<=;k++){
int x=i+xx[k],y=j+yy[k];
if(x>=&&x<=N&&y>=&&y<=M){
add(N*M+id(i,j),id(x,y),inf); add(id(x,y),N*M+id(i,j),);
}
}
}
for(i=;i<=N;i++)
for(j=;j<=M;j++){
scanf("%d",&x); ans+=x;
add(*N*M+id(i,j),T,x); add(T,*N*M+id(i,j),);
for(k=;k<=;k++){
int x=i+xx[k],y=j+yy[k];
if(x>=&&x<=N&&y>=&&y<=M){
add(id(x,y),*N*M+id(i,j),inf); add(*N*M+id(i,j),id(x,y),);
}
}
}
while(dis[S]<=T) maxflow+=sap(S,inf);
printf("%d\n",ans-maxflow);
return ;
}
BZOJ3894:文理分科(最大流)(同BZoj3438)的更多相关文章
- 【bzoj3894】文理分科 网路流
[bzoj3894]文理分科 2015年3月25日3,4002 Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班 ...
- [bzoj3894]文理分科_网络流_最小割
文理分科 bzoj-3894 题目大意:题目链接. 注释:略. 想法: 这种题也是一种套路. 我们新建一个点表示收益点. 然后把所有的收益都加一起,求最小割表示代价即可. Code: #include ...
- Bzoj3894 文理分科
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 667 Solved: 389 Description 文理分科是一件很纠结的事情!(虽然看到这个题 ...
- BZOJ3894文理分科——最小割
题目描述 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从 ...
- [Bzoj3894]文理分科(最小割)
Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位 ...
- bzoj3894: 文理分科(还是那道最小割)
3894: 文理分科 题目:传送门 感谢波老师没有来D飞我,让我做出了这题... 题解: 这题其实和我做的上一题(bzoj2132)很像,所以就不写题意了. 依然是那最小割... 这题给出了四个利益矩 ...
- 【题解】 bzoj3894: 文理分科 (网络流/最小割)
bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...
- [BZOJ3894]文理分科(最小割)
(1) 对每个位置建一个点F1,S向这个点连art[i][j]的边,这个点向T连science[i][j]的边. (2) 对每个位置再建一个点F2,S向这个点连same_art[i][j]的边,这个点 ...
- 【BZOJ3894】文理分科(最小割)
[BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个 ...
随机推荐
- Java进阶之自动拆箱与自动装箱
序. java基本类型介绍 java中,基本数据类型一共有8种,详细信息如下表: 类型 大小 范围 默认值 byte 8 -128 - 127 0 short 16 -32768 - 32768 0 ...
- apache配置ssl
1.确认是否安装ssl模块 是否有mod_ssl.so文件 2.生成证书和密钥 linux下 步骤1:生成密钥 命令:openssl genrsa 1024 > server.key 说 ...
- Git出现fatal: Unable to find remote helper for 'https'
使用Git远程获取代码 git clone https://github.com/twlkyao/findfile.git 出现“fatal: Unable to find remote helper ...
- mac 下 安装 mongodb
使用brew安装,不过brew不再更新, 通过 sudo chown -R $(whoami):admin /usr/local 这条语句终端有提醒的 xcode-select --install 需 ...
- vector的坑——C++primer练习6.33总结
说来惭愧,一道简单的对vector递归的题目写了一个多小时,最后还是请教了大神才改出来. 首先贴上原代码: void return_vector(vector<int>::iterator ...
- Linux CentOS 7 安装字体库 & 中文字体
前言 报表中发现有中文乱码和中文字体不整齐(重叠)的情况,首先考虑的就是操作系统是否有中文字体,在CentOS 7中发现输入命令查看字体列表是提示命令无效: 如上图可以看出,不仅没有中文字体,连字体库 ...
- SQLServer 2005 和自增长主键identity说再见——NEWSEQUENTIALID()
``code 在SQLServer2005环境下,表的主键应该怎样设计. 目前主要用到的主键方案共三种 自动增长主键 手动增长主键 UNIQUEIDENTIFIER主键 1.先说自动增长主键,它的优点 ...
- Apache的三种工作模式及相关配置
Apache的三种工作模式 作为老牌服务器,Apache仍在不断地发展,就目前来说,它一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块).它们分别是 prefor ...
- DSP基础学习-ADC采样
DSP基础学习-ADC采样 彭会锋 2015-04-27 22:30:03 在查看ADC采样例程的时候我发现了下面的代码挺有意思的 EALLOW; GpioCtrlRegs.GPAMUX2.bit.G ...
- mysql中一个字段根据另一字段的值分割为不同列
1.数据结构如下: vehicleId mileage_type mileage 11AM6897 0 120 11AM6897 1 60 13AY9180 0 ...