注意到所有学生分为文理两科实际是把所有学生分为两个集合,如果相邻点全为同一集合有额外贡献

与最小割模型类似,考虑用最小割来解这道题

所有割到s的集合的点如果相邻点有割到t集合的就要去掉共有贡献,但是不论他周围有多少与他不同的人,这个贡献只会被扣一次,所以考虑拆点

可以观察到如果一个点没有选择文科,那么也必然不会有文科共同贡献,理科亦然,所以考虑把选每科贡献与每科共同贡献统一起来

然后就可以构图了

设a[x]为x选文科满意度,s[x]为选理科满意度

Sa[x],Ss[x]分别为选两科的共同贡献

把每个点拆成三个点ux,x,dx,源向x连容量为a[x]+Sa[x]的边,x向汇连容量为s[x]+Ss[x]的边

x向ux连容量为Sa[x]的边,dx向x连容量为Ss[x]的边

ux向所有与x相邻的点连容量为INF的边,所有与x相邻的点向dx连容量为INF的边

跑最小割即可

代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;inline int _min(int a,int b) {return a<b?a:b;}#define MAXN 30005const int S=MAXN-3,T=MAXN-2;
int n,m,fix,fix2,ans;
struct Edge{int from,to,next,v;
}e[MAXN*10];
int cnt=1,head[MAXN];
inline void insert(int a,int b,int f) {e[++cnt].next=head[a];head[a]=cnt;e[cnt].v=f;e[cnt].to=b;e[cnt].from=a;e[++cnt].next=head[b];head[b]=cnt;e[cnt].v=0;e[cnt].to=a;e[cnt].from=b;
}int mk[105][105],sz,a[105][105],s[105][105],Sa[105][105],Ss[105][105];
int to[4][2]={1,0,0,1,-1,0,0,-1};int dis[MAXN],bk[MAXN];queue<int> q;
bool Bfs() {memset(dis,0,sizeof(dis));dis[T]=1;q.push(T);while(!q.empty()) {int now=q.front();q.pop();for(int i=head[now];i;i=e[i].next) if(!dis[e[i].to]&&e[i^1].v>0) {dis[e[i].to]=dis[now]+1;q.push(e[i].to);}}return dis[S];
}
int Dfs(int v,int a) {if(v==T) return a;int flow=0,k;for(int i=head[v];i;i=e[i].next) {if(e[i].v>0&&dis[e[i].to]==dis[v]-1) {k=Dfs(e[i].to,_min(a,e[i].v));a-=k;flow+=k;e[i].v-=k;e[i^1].v+=k;if(a==0) return flow;}}return flow;
}
int MaxFlow() {int flow=0,h;while(Bfs()) {while(h=Dfs(S,INF)) flow+=h;}return flow;
}int main() {scanf("%d%d",&n,&m);fix=n*m;fix2=n*m*2;for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {mk[i][j]=++sz;scanf("%d",&a[i][j]);}for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&s[i][j]);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&Sa[i][j]);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&Ss[i][j]);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {ans+=a[i][j]+s[i][j]+Sa[i][j]+Ss[i][j];insert(S,mk[i][j],a[i][j]+Sa[i][j]);insert(mk[i][j],T,s[i][j]+Ss[i][j]);}for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {insert(mk[i][j],mk[i][j]+fix,Sa[i][j]);insert(mk[i][j]+fix2,mk[i][j],Ss[i][j]);for(int k=0;k<4;k++) {if(!mk[i+to[k][0]][j+to[k][1]]) continue;insert(mk[i][j]+fix,mk[i+to[k][0]][j+to[k][1]],INF);insert(mk[i+to[k][0]][j+to[k][1]],mk[i][j]+fix2,INF);}}printf("%d\n",ans-MaxFlow());return 0;
}

转载于:https://www.cnblogs.com/ihopenot/p/6228593.html

Bzoj3894文理分科相关推荐

  1. BZOJ3894 文理分科

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

  2. BZOJ3894: 文理分科

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

  3. LuoguP4313 BZOJ3894 文理分科——最小割

    洛谷:文理分科 传送门 题目描述: 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择一科.同学们在选择科目的时候会获得一 ...

  4. bzoj3894 文理分科 最小割

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

  5. BZOJ3894:文理分科

    https://blog.csdn.net/PoPoQQQ/article/details/43968017 求最大收益->总收益-最小的丢失->最小割. 对于直接选文理很简单,直接把点分 ...

  6. BZOJ3894:文理分科——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3894 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理 ...

  7. [BZOJ 3894]文理分科(最小割)

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

  8. 文理分科 (最小割问题)

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

  9. P4313 文理分科 详细理解

    P4313 文理分科 网络其他地方看到的原话:在说这道题之前,让我们先思考一下最小割的性质.最小割就是使得s到t割掉的最小边的容量,割过之后,所有的点要么与s联通,要么与t联通. 这样的性质,即要么与 ...

  10. luoguP4313 文理分科

    luoguP4313 文理分科 复习完之后做了道典型题目. 这道题条件有点多 我们逐个分析 如果没有\(sameart\)或者\(samescience\)的限制,就是一个裸的最大权闭合子图的问题了 ...

最新文章

  1. SAP Data Intelligence API执行出错的排错之道
  2. Python(3)-Pycharm基本使用技巧
  3. 基于python的图书管理系统测试步骤_Django admin实现图书管理系统菜鸟级教程完整实例...
  4. php千封邮件怎么快速发送,如何在PHP中无限制地发送数千封电子邮件?
  5. 并查集 (Union-Find)算法
  6. JavaScript设计模式与开发实践---读书笔记(6) 代理模式
  7. vue路由加载页面时,数据返回慢的问题
  8. 剪映电脑版_插上手机秒变2K屏笔记本!TNT go扩展本评测:欢迎使用下一代电脑...
  9. java单人多人聊天_java简单多人聊天
  10. 深度学习(目标检测。图像分割等)图像标注工具汇总
  11. html多行文本框_HTML的七大标签怎么运用?
  12. 大数据——Python数据爬取
  13. 数字信号处理《数字滤波器的MATLAB与FPGA实现》
  14. adc0808温度换算公式_多路温度采集与控制(C51、ADC0808)
  15. [15元]人体行为检测和识别毕业论文讲述
  16. C/C++去除行末空格
  17. Crossbar技术冲破网络容量瓶颈
  18. 简单使用一下IDEA 的HTTP Client
  19. Python 调用 C++
  20. 游久刘亮:从最具草莽气质的80后 到上市公司CEO

热门文章

  1. 简易web服务器系统毕业论文设计,毕业论文 简易的WEB服务器的设计
  2. 面试题--------3、string stringbuffer stringbuilder的区别
  3. linux板级设备的,linux板级设备的初始化过程是怎样的?
  4. 7.监控应用和数据可视化 7.1通用健康状态指引器
  5. Spring源码之bean的加载(三)从bean中获取对象
  6. 【渝粤教育】国家开放大学2018年春季 0032-22T农业经济学 参考试题
  7. 【渝粤题库】陕西师范大学165101社会学 作业(高起专)
  8. 基于频繁增长树(FP-树)的频繁项集挖掘算法实现
  9. Maxent Source code reading experience
  10. 【ICLR 2018】模型集成的TRPO算法【附代码】