我们不妨想一想,这道题目又有\(abs\)又有\(Max\)不是很好算对吧.

所以我们二分答案,考虑怎么\(check\).

对于一个点,显然它能够取的范围是\([l,r]\),接着是对于一行一列都有一个限制使得满足题目条件.

然后直接跑上下界可行流即可.

/*
mail: mleautomaton@foxmail.com
author: MLEAutoMaton
This Code is made by MLEAutoMaton
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi(){
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=20010,Inf=1e9+10;
int ans,cnt,front[N],dep[N],delta[N],s,t,n,m,a[210][210],l,r,ss,tt,cur[N];queue<int>Q;
int lie[210],hang[210];
struct node{int to,nxt,w;}e[N*100];
void Add(int u,int v,int w){
e[cnt]=(node){v,front[u],w};front[u]=cnt++;
e[cnt]=(node){u,front[v],0};front[v]=cnt++;
}
bool bfs(){
Q.push(ss);memset(dep,0,sizeof(dep));dep[ss]=1;
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=front[u];~i;i=e[i].nxt){
int v=e[i].to;
if(!dep[v] && e[i].w){
dep[v]=dep[u]+1;Q.push(v);
}
}
}
return dep[tt];
}
int dfs(int u,int flow){
if(!flow || u==tt)return flow;
for(int &i=cur[u];~i;i=e[i].nxt){
int v=e[i].to;
if(dep[v]==dep[u]+1 && e[i].w){
int di=dfs(v,min(flow,e[i].w));
if(di){
e[i].w-=di;e[i^1].w+=di;return di;
}
else dep[v]=0;
}
}
return 0;
}
int Dinic(){
int flow=0;
while(bfs()){
for(int i=0;i<=tt;i++)cur[i]=front[i];
while(int d=dfs(ss,Inf))flow+=d;
}
return flow;
}
int build(int mid){
memset(front,-1,sizeof(front));cnt=0;int sum=0;
memset(delta,0,sizeof(delta));
s=0;t=n+m+1;ss=t+1;tt=ss+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
Add(i,j+n,r-l);
delta[i]-=l;delta[j+n]+=l;
}
for(int i=1;i<=n;i++){
int L=hang[i]-mid,R=hang[i]+mid;
Add(s,i,R-L);
delta[s]-=L;delta[i]+=L;
}
for(int i=1;i<=m;i++){
int L=lie[i]-mid,R=lie[i]+mid;
Add(i+n,t,R-L);
delta[t]+=L;delta[i+n]-=L;
}
for(int i=s;i<=t;i++)
if(delta[i]>0)Add(ss,i,delta[i]),sum+=delta[i];
else Add(i,tt,-delta[i]);
Add(t,s,Inf);
return sum;
}
bool check(int mid){
int sum=build(mid);
int flow=Dinic();
return flow>=sum;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
#endif
n=gi();m=gi();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
a[i][j]=gi();
lie[j]+=a[i][j];hang[i]+=a[i][j];
}
l=gi();r=gi();
int L=0,R=10000000,ret=0;
while(L<=R){
int mid=(L+R)>>1;
if(check(mid)){ret=mid;R=mid-1;}
else L=mid+1;
}
printf("%d\n",ret);
return 0;
}

bzoj2406 矩阵的更多相关文章

  1. BZOJ2406矩阵——有上下界的可行流+二分答案

    题目描述 输入 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. 输出 第一行,输出最小的答案: 样例输入 2 2 0 1 2 1 0 1 样例输出 1 ...

  2. bzoj千题计划158:bzoj2406: 矩阵(有源汇上下界可行流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2406 设矩阵C=A-B 最小化 C 一行或一列和的最大值 整体考虑一行或者一列的和 二分最大值 这样 ...

  3. 【上下界网络流 二分】bzoj2406: 矩阵

    感觉考试碰到上下界网络流也还是写不来啊 Description Input 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. Output 第一行,输出 ...

  4. BZOJ2406矩阵

    题目描述 题解 最大值最小,一眼二分没的说. 然后考虑建出这么个图,每行看做一个点,每列看做一个点,每个点看做一条连接行与列的边,源点向每行连s-mid__s+mid的边,行与列连L__R的边,列到汇 ...

  5. 【BZOJ】2406 矩阵

    [算法]二分+有源汇上下界可行流 [题解]上下界 题解参考:[BZOJ2406]矩阵(二分+有源汇有上下界的可行流) #include<cstdio> #include<algori ...

  6. 【BZOJ2406】矩阵 二分+有上下界的可行流

    [BZOJ2406]矩阵 Description Input 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. Output 第一行,输出最小的答案: ...

  7. 【bzoj2406】矩阵 二分+有上下界可行流

    题目描述 输入 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. 输出 第一行,输出最小的答案: 样例输入 2 2 0 1 2 1 0 1 样例输出 1 ...

  8. C语言 · 矩阵乘法 · 算法训练

    问题描述 输入两个矩阵,分别是m*s,s*n大小.输出两个矩阵相乘的结果. 输入格式 第一行,空格隔开的三个正整数m,s,n(均不超过200). 接下来m行,每行s个空格隔开的整数,表示矩阵A(i,j ...

  9. 获取Canvas当前坐标系矩阵

    前言 在我的另一篇博文 Canvas坐标系转换 中,我们知道了所有的平移缩放旋转操作都会影响到画布坐标系.那在我们对画布进行了一系列操作之后,怎么再知道当前矩阵数据状态呢. 具体代码 首先请看下面的一 ...

随机推荐

  1. centos7上使用git clone出现问题

    centos 7  git clone时出现不支持协议版本的问题 unable to access 'https://github.com/baloonwj/TeamTalk.git/': Peer ...

  2. 关于 table 那些事儿

    一.  table thead/tbody/tfoot 组合写法: table: 表格: thead: 表头: tbody: 标签表格主体(正文): tr:行: th:表头单元格 td:单元格: tb ...

  3. STM8 内部flash

    举例 typedef enum { FLASH_MEMTYPE_PROG = (u8)0x00, /*!< Program memory */ FLASH_MEMTYPE_DATA = (u8) ...

  4. angular-cli 引入ui组件库

    该例中使用的admin-lte以及bootstrap 1.使用npm 安装admin-lte命令: npm install admin-lte --save  (--save的意思是将该以来写入到pa ...

  5. 元组和range

    元组 只读列表,不支持增 删 改:但是元组里的列表可以增删改 元组其实就是通过逗号(,)设定的,和小括号并没有什么必然的关系,所以当元组只有一个元素的时候,需要在元素后加个逗号 存储大量数据,有序.不 ...

  6. openwrt双机热备

    转自:https://oldwiki.archive.openwrt.org/doc/recipes/high-availability 先记号一下,有空再仔细研究. ---------------- ...

  7. springboot 配置 中查找application.properties中对应的数据,添加对应的prefix前缀

    @ConditionalOnProperty(prefix = "spring.redis", name = "enabled", havingValue = ...

  8. linux网络编程之socket编程(十二)

    今天继续学习socket编程,期待的APEC会议终于在京召开了,听说昨晚鸟巢那灯火通明,遍地礼花,有点08年奥运会的架势,有种冲动想去瞅见一下习大大的真容,"伟大的祖国,我爱你~~~&quo ...

  9. Oracle递归查询connect by

    一.概述 Oracle中可以通过START WITH . . . CONNECT BY . . .子句来实现SQL的层次查询. 自从Oracle 9i开始,可以通过 SYS_CONNECT_BY_PA ...

  10. Codeforces#572 Div2 C---Candies!【倍增】【DP】【思维】

    题目:http://codeforces.com/contest/1189/problem/C 题意:给定n个数,每次查询一个区间$[l,r]$.对这个区间内的数,相邻两个数之和超过10,则得到一个c ...