[题解] 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)

相关推荐

  • AspNetCore应用注意哪些点

    技术AspNetCore应用注意哪些点今天就跟大家聊聊有关AspNetCore应用注意哪些点,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。背景已经有很多文章记录了

    攻略 2021年11月18日
  • Java并发编程相关概念及注意事项是什么

    技术Java并发编程相关概念及注意事项是什么Java并发编程相关概念及注意事项是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。相应的概念

    攻略 2021年10月23日
  • 迷你图的散点图是什么

    技术sparklines的ScatterChart是什么本篇内容主要讲解“sparklines的ScatterChart是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“s

    攻略 2021年12月16日
  • sparklines是什么意思(sparklines的BoxPlot是什么)

    技术sparklines的BoxPlot是什么本篇内容主要讲解“sparklines的BoxPlot是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sparklines的

    攻略 2021年12月16日
  • 源码编译怎么安装PostgresSQL

    技术源码编译怎么安装PostgresSQL这篇文章主要讲解了“源码编译怎么安装PostgresSQL”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“源码编译怎么安装Post

    攻略 2021年11月4日
  • Oracle GoldenGate配置参数分析

    技术Oracle GoldenGate配置参数分析这篇文章主要介绍“Oracle GoldenGate配置参数分析”,在日常操作中,相信很多人在Oracle GoldenGate配置参数分析问题上存在疑惑,小编查阅了各式

    攻略 2021年11月15日