[题解] bzoj3894 文理分科

技术[题解] bzoj3894 文理分科 [题解] bzoj3894 文理分科题目链接
题目描述
\(n\) 行 \(m\) 列的矩阵,每个人可以选文科或者理科。第 \(i,j\) 个人选文科贡献为 \

[题解] bzoj3894文理分科

题目链接

题目描述

\(n\)行\(m\)列的矩阵,每个人可以选文科或者理科。第\(i,j\)个人选文科贡献为\(a_{i,j}\),选理科贡献为\(b_{i,j}\),周围及自己选文科贡献为\(c_{i,j}\),周围及自己选理科贡献为\(d_{i,j}\)。

思路

建图方法见代码。

利用最大权闭合子图,考虑全选文科,初始值为\(\sum a_{i,j} c_{i,j}\)。

那么理科的贡献就为\(b_{i,j}\),全选理科的贡献为\(d_{i,j}\)。

不选文科的贡献为\(-a_{i,j}\),\(5\)人之中有一个不选的贡献为\(-c_{i,j}\)。

则内部构图中,有三个约束条件:

选了理科,则必不选文科。

选了\(d_{i,j}\),则四周及自己都必须选理科。

选了一个不选文科,则与这个点相关的\(c_{i,j}\)都必须破坏,及必选相关的\(-c_{i,j}\)。

则答案为\(\ sum a _ { I,j} b_{i,j} c_{i,j} d_{i,j})-mincut\)。

Code

#包含cstdio

#定义INF0x3f3f

const int MAXN=2e5 5

const int MaxM=1e 6 5;

结构边缘{ int To,Cap,Next}边[MAXM 1];

int head[MAXN],tot=1;

void Addedge(int u,int v,int w){ 0

边缘[ tot].下一个=头[u],边[tot]。To=v,edge[tot].Cap=w,head[u]=tot;

边缘[ tot].下一个=头部[v],边缘[tot].To=u,edge[tot].Cap=0,head[v]=tot;

}

int cur[MAXN],dep[MAXN],que[MAXN],qhead,qtail

int n,m,s,t;

int addx[]={0,0,1,-1,0 };

int addy[]={1,-1,0,0,0 };

int ans

int Min(int x,int y){ return x y x :y;}

布尔bfs(布尔限制){ 0

for(int I=s;I=t;i ) dep[i]=0,cur[I]=head[I];

qhead=1;qtail=1;que[1]=t;dep[t]=1;

while(qhead=qtail){ 0

int u=que[qhead];

for(int I=head[u];我;i=edge[i].下一个){ 0

int v=edge[i].到;

if(!副[v]边[i ^ 1].Cap(!限制||!(一(1)))(

dep[v]=dep[u]1;

que[qtail]=v;

if (v==s)返回1;

}

}

}

返回0;

}

int dfs(int u,int flow){ 0

if(u==t ||!流量)回流;

int rest=flow

for(int I=cur[u];我休息;i=edge[i].下一个){ 0

cur[u]=I;

int v=edge[i].到;

if(dep[v]==dep[u] - 1边[i].Cap) {

int del=dfs(v,Min(静止,边缘[i]).cap));

rest-=del;边缘cap-=del;边缘[我^ 1]。Cap=del

if(!del)dep[v]=-2;

}

}

回流休息;

}

int Dinic(){ 0

int res=0,流;

while (bfs(1)) while ((flow=dfs(s,INF)))RES=flow;

while (bfs(0)) while ((flow=dfs(s,INF)))RES=flow;

返回表示留数

}

int Get(int x,int y,int h){ 0

return(x-1)* m y n * m * h;

}

int main(){ 0

scanf('%d %d ',n,m);

s=0,t=4 * n * m ^ 1;

for(int I=1;I=n;I){ 0

for (int j=1,a;j=m;j ) {

scanf("% d ",a);

Addedge(Get(i,j,0),t,a);

ans=a;

}

}

for(int I=1;I=n;I){ 0

for (int j=1,a;j=m;j ) {

scanf("% d ",a);

Addedge(s,Get(i,j,1),a);

Addedge(Get(i,j,1),Get(i,j,0),INF);

ans=a;

}

}

for(int I=1;I=n;I){ 0

for (int j=1,a;j=m;j ) {

scanf("% d ",a);

Addedge(Get(i,j,2),t,a);

ans=a;

for(int k=0;K5;k){ 0

int ni=I addx[k];

int NJ=j addy[k];

if (ni 1 || ni n || nj 1 || nj m)继续;

Addedge(Get(ni,nj,0),Get(i,j,2),INF);

}

}

}

for(int I=1;I=n;I){ 0

for (int j=1,a;j=m;j ) {

scanf("% d ",a);

ans=a;

Addedge(s,Get(i,j,3),a);

for(int k=0;K5;k){ 0

int ni=I addx[k];

int NJ=j addy[k];

if (ni 1 || ni n || nj 1 || nj m)继续;

Addedge(Get(i,j,3),Get(ni,nj,1),INF);

}

}

}

printf('%d ',ans-Dinic());

返回0;

}

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/141448.html

(0)

相关推荐

  • C++中signed main和int main有哪些区别

    技术C++中signed main和int main有哪些区别这篇文章给大家分享的是有关C++中signed main和int main有哪些区别的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

    攻略 2021年12月10日
  • 简述storm的拓扑结构(storm拓扑原理)

    技术storm怎么构建拓扑代码这篇文章主要讲解了“storm怎么构建拓扑代码”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“storm怎么构建拓扑代码”吧!1. 构建拓扑

    攻略 2021年12月23日
  • Java的流程控制语句有哪些

    技术Java的流程控制语句有哪些本篇内容介绍了“Java的流程控制语句有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成

    攻略 2021年10月25日
  • python字典一些常见的魔法方法以及遇到的面试题有哪些

    技术python字典一些常见的魔法方法以及遇到的面试题有哪些本篇文章给大家分享的是有关python字典一些常见的魔法方法以及遇到的面试题有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,

    攻略 2021年10月21日
  • Hibernate有哪些优势

    技术Hibernate有哪些优势这篇文章主要为大家展示了“Hibernate有哪些优势”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Hibernate有哪些优势”这篇文章吧。

    攻略 2021年12月8日
  • 视觉皮层的架构

    技术视觉皮层的架构 视觉皮层的架构视觉皮层的架构
    卷积神经网络(CNN)起源于对大脑的视觉皮层的研究,从20世纪80年代起被用于图像识别。在过去几年中,由于计算机计算能力的提高、可训练数据数量的增加,以

    礼包 2021年11月14日