文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠
结过)
小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)的更多相关文章

  1. 【bzoj3894】文理分科 网路流

    [bzoj3894]文理分科 2015年3月25日3,4002 Description  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过)  小P所在的班级要进行文理分科.他的班 ...

  2. [bzoj3894]文理分科_网络流_最小割

    文理分科 bzoj-3894 题目大意:题目链接. 注释:略. 想法: 这种题也是一种套路. 我们新建一个点表示收益点. 然后把所有的收益都加一起,求最小割表示代价即可. Code: #include ...

  3. Bzoj3894 文理分科

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 667  Solved: 389 Description  文理分科是一件很纠结的事情!(虽然看到这个题 ...

  4. BZOJ3894文理分科——最小割

    题目描述  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过)  小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从 ...

  5. [Bzoj3894]文理分科(最小割)

    Description  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过)  小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位 ...

  6. bzoj3894: 文理分科(还是那道最小割)

    3894: 文理分科 题目:传送门 感谢波老师没有来D飞我,让我做出了这题... 题解: 这题其实和我做的上一题(bzoj2132)很像,所以就不写题意了. 依然是那最小割... 这题给出了四个利益矩 ...

  7. 【题解】 bzoj3894: 文理分科 (网络流/最小割)

    bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...

  8. [BZOJ3894]文理分科(最小割)

    (1) 对每个位置建一个点F1,S向这个点连art[i][j]的边,这个点向T连science[i][j]的边. (2) 对每个位置再建一个点F2,S向这个点连same_art[i][j]的边,这个点 ...

  9. 【BZOJ3894】文理分科(最小割)

    [BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个 ...

随机推荐

  1. 回文树 Palindromic Tree

    回文树 Palindromic Tree 嗯..回文树是个什么东西呢. 回文树(或者说是回文自动机)每个节点代表一个本质不同的回文串. 首先它类似字典树,每个节点有SIGMA个儿子,表示对应的字母. ...

  2. /nagios/cgi-bin/cmd.cgi无法打开

    原因分析,nginx不支持post. 解决方法,重新编译nagios 1.vi /nagios-4.0.8/cgi/cmd.c 找到printf("<form method='post ...

  3. springboot Actuator健康检查

    通过情况下,如我们想在系统中添加一个健康检查的接口,我们怎么做呢? 我们会新建一个类,或在已存在类的基础上添加检测接口. package com.crhms.medicareopinion; impo ...

  4. ng-options 如何实现其中一项option禁选

    <select class="form-control" ng-model="functionPaymentMethod" ng-options=&quo ...

  5. 记录一下我的mac的环境变量的配置参数

    #配置jdk环境export JAVA_7_HOME=/Library/java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Homeexport JAV ...

  6. iOS 可变字符串NSMutableString的使用

    .创建一个可变字符串 NSMutableString * ms1 = [[NSMutableString alloc]init]; .可以通过类方法来创建 NSMutableString * ms2 ...

  7. android AVD启动失败原因之一

    在mac上安装好Android SDK.AVD及相关的组件之后,手动创建了一个安卓模拟器后,通过actions启动,会弹出一个提示窗口,然后就闪退,也没有报错什么的,在网上搜了半天AVD启动失败的问题 ...

  8. [PostgreSql]PostgreSql创建函数及函数的执行

    1.准备好创建函数的脚本 -- FUNCTION: public.dynamic_placelist_select(integer, timestamp without time zone) -- D ...

  9. AngularJS 教程 - CodePreject

    http://www.codeproject.com/Articles/1065838/AngularJS-Tutorial Article Series Tutorial 1: Angular JS ...

  10. Performance js

    转贴:https://10up.github.io/Engineering-Best-Practices/javascript/#performance Performance Writing per ...