题面

BZOJ传送门

Luogu传送门

分析

这道题又出现了二元关系,于是我们只需要解方程确定怎么连边就行了



假设跟SSS分在一块是选文科,跟TTT分在一块是选理科,先加上所有的收益,再来考虑如何让需要减去的代价最小.我们来看看代价的方程

定义AAA表示选文科的收益,BBB表示选理科的收益,有:

  • a+b=Ax+Ay+Ax,y\large a+b=A_x+A_y+A_{x,y}a+b=Ax​+Ay​+Ax,y​
  • c+d=Bx+By+Bx,y\large c+d=B_x+B_y+B_{x,y}c+d=Bx​+By​+Bx,y​
  • a+e+d=Ax+By+Ax,y+Bx,y\large a+e+d=A_x+B_y+A_{x,y}+B_{x,y}a+e+d=Ax​+By​+Ax,y​+Bx,y​
  • b+e+c=Bx+Ay+Ax,y+Bx,y\large b+e+c=B_x+A_y+A_{x,y}+B_{x,y}b+e+c=Bx​+Ay​+Ax,y​+Bx,y​

能够解出来

  • a=Ax+Ax,y2\large a=A_x+\frac{A_{x,y}}2a=Ax​+2Ax,y​​
  • b=Ay+Ax,y2\large b=A_y+\frac{A_{x,y}}2b=Ay​+2Ax,y​​
  • c=Bx+Bx,y2\large c=B_x+\frac{B_{x,y}}2c=Bx​+2Bx,y​​
  • d=By+Bx,y2\large d=B_y+\frac{B_{x,y}}2d=By​+2Bx,y​​
  • e=Ax,y2+Bx,y2\large e=\frac{A_{x,y}}2+\frac{B_{x,y}}2e=2Ax,y​​+2Bx,y​​

所以我们只需要把边权乘以二做最小割,然后用所有收益减去最小割的答案除以2就行了.

CODE

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct && (ct = (cs = cb) + fread(cb , 1 , 1<<15 , stdin),cs==ct)?0:*cs++)
template<typename T>inline void read(T &num) {
char ch; while((ch=getchar())<'0'||ch>'9');
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
} const int inf = 1e9;
const int MAXN = 10005;
const int MAXM = 2000005;
const int dx[] = { 1, -1, 0, 0, 0 };
const int dy[] = { 0, 0, -1, 1, 0 };
int n, m, fir[MAXN], S, T, cnt;
struct edge { int to, nxt; int c; }e[MAXM];
inline void add(int u, int v, int cc, int rc=0) {
e[cnt] = (edge){ v, fir[u], cc }; fir[u] = cnt++;
e[cnt] = (edge){ u, fir[v], rc }; fir[v] = cnt++;
}
int dis[MAXN], vis[MAXN], info[MAXN], cur, q[MAXN];
inline bool bfs() {
int head = 0, tail = 0;
vis[S] = ++cur; q[tail++] = S;
while(head < tail) {
int u = q[head++];
for(int i = fir[u]; ~i; i = e[i].nxt)
if(e[i].c && vis[e[i].to] != cur)
vis[e[i].to] = cur, dis[e[i].to] = dis[u] + 1, q[tail++] = e[i].to;
}
if(vis[T] == cur) memcpy(info, fir, (T+1)<<2);
return vis[T] == cur;
}
int dfs(int u, int Max) {
if(u == T || !Max) return Max;
int flow=0, delta;
for(int &i = info[u]; ~i; i = e[i].nxt)
if(e[i].c && dis[e[i].to] == dis[u] + 1 && (delta=dfs(e[i].to, min(e[i].c, Max-flow)))) {
e[i].c -= delta, e[i^1].c += delta, flow += delta;
if(flow == Max) return flow;
}
return flow;
}
inline int dinic() {
int flow=0, x;
while(bfs()) {
while((x=dfs(S, inf))) flow+=x;
}
return flow;
}
int sum, tmps[MAXN], tmpt[MAXN], A[105][105], B[105][105];
inline int enc(int i, int j) { return (i-1)*m + j; }
int main () {
memset(fir, -1, sizeof fir);
read(n); read(m); S = 0; T = n*m+1;
for(int i = 1, x; i <= n; ++i)for(int j = 1; j <= m; ++j)read(x), sum += x, tmps[enc(i,j)] += 2*x;
for(int i = 1, x; i <= n; ++i)for(int j = 1; j <= m; ++j)read(x), sum += x, tmpt[enc(i,j)] += 2*x;
for(int i = 1; i < n; ++i)for(int j = 1; j <= m; ++j)read(A[i][j]), sum += A[i][j], tmps[enc(i,j)] += A[i][j], tmps[enc(i+1,j)] += A[i][j];
for(int i = 1; i < n; ++i)for(int j = 1; j <= m; ++j)read(B[i][j]), sum += B[i][j], tmpt[enc(i,j)] += B[i][j], tmpt[enc(i+1,j)] += B[i][j];
for(int i = 1; i < n; ++i)for(int j = 1; j <= m; ++j)add(enc(i, j), enc(i+1, j), A[i][j]+B[i][j], A[i][j]+B[i][j]);
for(int i = 1; i <= n; ++i)for(int j = 1; j < m; ++j)read(A[i][j]), sum += A[i][j], tmps[enc(i,j)] += A[i][j], tmps[enc(i,j+1)] += A[i][j];
for(int i = 1; i <= n; ++i)for(int j = 1; j < m; ++j)read(B[i][j]), sum += B[i][j], tmpt[enc(i,j)] += B[i][j], tmpt[enc(i,j+1)] += B[i][j];
for(int i = 1; i <= n; ++i)for(int j = 1; j < m; ++j)add(enc(i, j), enc(i, j+1), A[i][j]+B[i][j], A[i][j]+B[i][j]);
for(int i = 1; i <= n*m; ++i) {
if(tmps[i]) add(S, i, tmps[i]);
if(tmpt[i]) add(i, T, tmpt[i]);
}
printf("%d\n", sum-dinic()/2);
}

BZOJ 2127 / Luogu P1646 [国家集训队]happiness (最小割)的更多相关文章

  1. luogu P1646 [国家集训队]happiness (最小割)

    高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科 ...

  2. [国家集训队]happiness 最小割 BZOJ 2127

    题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...

  3. BZOJ 2152 / Luogu P2634 [国家集训队]聪聪可可 (点分治/树形DP)

    题意 一棵树,给定边权,求满足两点之间的路径上权值和为3的倍数的点对数量. 分析 点分治板题,对每个重心求子树下面的到根的距离模3分别为0,1,2的点的个数就行了. O(3nlogn)O(3nlogn ...

  4. luogu P2757 [国家集训队]等差子序列

    题目链接 luogu P2757 [国家集训队]等差子序列 题解 线段树好题 我选择暴力 代码 // luogu-judger-enable-o2 #include<cstdio> inl ...

  5. luogu P2619 [国家集训队2]Tree I

    题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...

  6. [Luogu P1829] [国家集训队]Crash的数字表格 / JZPTAB (莫比乌斯反演)

    题面 传送门:洛咕 Solution 调到自闭,我好菜啊 为了方便讨论,以下式子\(m>=n\) 为了方便书写,以下式子中的除号均为向下取整 我们来颓柿子吧qwq 显然,题目让我们求: \(\l ...

  7. [置顶] [BZOJ]2127: happiness 最小割

    happiness: Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己 ...

  8. BZOJ 2039:[2009国家集训队]employ人员雇佣(最小割)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2039 题意:中文题意. 思路:一开始想着和之前做的最大权闭合图有点像,但是如果把边全部当成点的话,那 ...

  9. BZOJ 2150 cogs 1861 [国家集训队2011]部落战争

    题目描述 lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土. A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住.lanzerb把 ...

随机推荐

  1. 记crt 在windows与linux服务器之间利用ftp进行文件的上传下载

    我们首先来熟悉一些相关的命令以及操作: ls      #展示linux服务器当前工作目录[你连接sftp时所处的目录]下的所有文件以及文件夹 lcd  F:\niki      #绑定你在windo ...

  2. K8S从入门到放弃系列-(2)集群根证书准备

    k8s从1.8版本开始,集群中各个组件需要使用TLS证书对通信进行加密,每个k8s集群都需要有独立的CA证书体系,这里我们采用比较常用的CloudFlare 的 PKI 工具集 cfssl 来生成 C ...

  3. java源码 -- AbstractSet

    AbstractSet抽象类属于Set集合分支的顶层类,它继承了AbstractCollection,实现了Set接口. public abstract class AbstractSet<E& ...

  4. JVM —— 类文件结构(上)

    一.概述 实现语言无关性的基础仍然是虚拟机和字节码存储格式.java虚拟机不和包括java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联,Class文件中包含了java虚拟 ...

  5. VC++操作注册表(创建,读取,更改,删除)

    #include "stdafx.h" #include <Windows.h> #include <iostream> using namespace s ...

  6. scratch少儿编程第一季——01、初识图形化界面编程的神器

    各位小伙伴大家好: 说到2018年互联教育的热门事件,那就不得不提Scratch. 相信各位不关注信息技术领域的各位家长也都听说过这个东西. 对于小学阶段想要接触编程或信息技术学生来说,Scratch ...

  7. SAS学习笔记34 指针控制

    指针控制符分为行指针和列指针两种 列指针控制符模式 @n:指明列的开始位置,是对应变量的数据开始列位置 列控制符号模式 n1-n2:n1列开始位置,n2列结束位置 @与@@符号应用 @行控制符号,控制 ...

  8. [二叉树算法]让树所有叶子节点连成一个单链表,让rchild作为 next指针

    //让树所有叶子节点连成一个单链表,让rchild作为 next指针 LNode *head=null,*pre=null;//全局变量 LNode *InOrder(BTNode *T){ if(T ...

  9. MogileFS表说明

    MogileFS大致的表说明如下 checksum:用来存放文件的校验和class:文件分类定义device:主机上的可用设备定义,包括设备可用空间,使用的权重等信息domain:域定义信息file: ...

  10. (二)手动配置第一个HelloWorld程序

    上例的HelloWorld是由Android sutudio 自动生成的,现在我们手动来配置. 1. 重新创建工程 2. 创建空的Activity 生成的MainActivity.java 文件: p ...