Description

有一个M * N的棋盘,有的格子是障碍。现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵。我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵, 第j列至少放置了Cj个士兵。现在你的任务是要求使用最少个数的士兵来占领整个棋盘。

Input

第一行两个数M, N, K分别表示棋盘的行数,列数以及障碍的个数。 第二行有M个数表示Li。 第三行有N个数表示Ci。 接下来有K行,每行两个数X, Y表示(X, Y)这个格子是障碍。

Output

输出一个数表示最少需要使用的士兵个数。如果无论放置多少个士兵都没有办法占领整个棋盘,输出”JIONG!” (不含引号)

Sample Input

4 4 4
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3

Sample Output

4
数据范围
M, N <= 100, 0 <= K <= M * N

Solution

有源汇上下界最小流……按行和列建二分图,分别向源汇点建立上下界为$[L_i,INF]$和$[C_i,INF]$的边,然后没有障碍点的两两连$[0,1]$的边,跑一遍就完了。

一个上下界网络流讲的很好的博客。注意别忘了$s$和$t$也要与$ss$和$tt$连边!

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N (20009)
#define INF (0x7f7f7f7f)
using namespace std; struct Edge{int to,next,flow;}edge[N*];
int n,m,k,vis[][];
int s=,t=,ss=,tt=;
int Depth[N],A[N];
int head[N],num_edge;
queue<int>q; inline int read()
{
int x=,w=; char c=getchar();
while (!isdigit(c)) {if (c=='-') w=-; c=getchar();}
while (isdigit(c)) x=x*+c-'', c=getchar();
return x*w;
} void add(int u,int v,int l)
{
edge[++num_edge].to=v;
edge[num_edge].next=head[u];
edge[num_edge].flow=l;
head[u]=num_edge;
} void Add(int u,int v,int l,int r)
{
add(u,v,r-l); add(v,u,);
A[u]-=l; A[v]+=l;
} int DFS(int x,int low,int t)
{
if (x==t || !low) return low;
int f=;
for (int i=head[x]; i; i=edge[i].next)
if (Depth[edge[i].to]==Depth[x]+)
{
int Min=DFS(edge[i].to,min(low,edge[i].flow),t);
edge[i].flow-=Min;
edge[((i-)^)+].flow+=Min;
f+=Min; low-=Min;
if (!low) break;
}
if (!f) Depth[x]=-;
return f;
} bool BFS(int s,int t)
{
memset(Depth,,sizeof(Depth));
Depth[s]=; q.push(s);
while (!q.empty())
{
int x=q.front(); q.pop();
for (int i=head[x]; i; i=edge[i].next)
if (!Depth[edge[i].to] && edge[i].flow)
{
Depth[edge[i].to]=Depth[x]+;
q.push(edge[i].to);
}
}
return Depth[t];
} int Dinic(int s,int t)
{
int ans=;
while (BFS(s,t)) ans+=DFS(s,INF,t);
return ans;
} int main()
{
n=read(); m=read(); k=read(); s=n+m+; t=s+;
for (int i=; i<=n; ++i) Add(s,i,read(),INF);
for (int i=; i<=m; ++i) Add(i+n,t,read(),INF);
for (int i=; i<=k; ++i) vis[read()][read()]=;
for (int i=; i<=n; ++i)
for (int j=; j<=m; ++j)
if (!vis[i][j]) Add(i,j+n,,);
int sum=;
for (int i=; i<=n+m+; ++i)
if (A[i]>) sum+=A[i], add(ss,i,A[i]), add(i,ss,);
else add(i,tt,-A[i]), add(tt,i,);
add(t,s,INF); add(s,t,);
if (Dinic(ss,tt)!=sum) {puts("JIONG!"); return ;}
for (int i=head[ss]; i; i=edge[i].next) edge[i].flow=edge[((i-)^)+].flow=;
for (int i=head[tt]; i; i=edge[i].next) edge[i].flow=edge[((i-)^)+].flow=;
int flow0=edge[num_edge].flow;
edge[num_edge].flow=edge[num_edge-].flow=;
printf("%d\n",flow0-Dinic(t,s));
}

BZOJ1458:士兵占领(有上下界最小流)的更多相关文章

  1. 【bzoj1458】士兵占领 有上下界最小流

    题目描述 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵 ...

  2. BZOJ 1458 / Luogu P4311 士兵占领 (上下界最小流 / 直接最大流)

    做法1:上下界最小流 先来一发上下界最小流,思路比较暴力,就是把行和列看作n+mn+mn+m个点,(i,j)(i,j)(i,j)如果能占领就从第iii行向第jjj列连一条边,上界为1下界为0;然后从s ...

  3. 【BZOJ】1458: 士兵占领(上下界网络流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1458 是不是我脑洞太小了.......直接弄上下界最小流........(就当复习了.. 二分图X和 ...

  4. 【bzoj2150】部落战争 有上下界最小流

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

  5. sgu 176 Flow construction(有源汇的上下界最小流)

    [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11025 [模型] 有源汇点的上下界最小流.即既满足上下界又满足 ...

  6. BZOJ_2502_清理雪道_有源汇上下界最小流

    BZOJ_2502_清理雪道_有源汇上下界最小流 Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...

  7. 【Loj117】有源汇上下界最小流(网络流)

    [Loj117]有源汇上下界最小流(网络流) 题面 Loj 题解 还是模板题. #include<iostream> #include<cstdio> #include< ...

  8. SGU 176 Flow construction (有源有汇有上下界最小流)

    题意:给定 n 个点,m 条有向边,如果有向边的标号是1的话,就表示该边的上界下界都为容量 ,如果有向边的标号为0的哈,表示该边的下界为0,上界为容量 ,现在问,从 1 到 n 的最小流是多少,并输出 ...

  9. loj #117. 有源汇有上下界最小流

    题目链接 有源汇有上下界最小流,->上下界网络流 注意细节,边数组也要算上后加到SS,TT边. #include<cstdio> #include<algorithm> ...

随机推荐

  1. Spring源码分析:非懒加载的单例Bean初始化过程(下)

    上文Spring源码分析:非懒加载的单例Bean初始化过程(上),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下AbstractAutowireC ...

  2. 用MVC5+EF6+WebApi 做一个小功能(四) 项目分层功能以及文件夹命名

    在上一节,我们完成了一个项目搭建,我们看到的是一个项目的分层架子,那接下来每一层做什么以及需要引用哪些内容呢?在本节内容我们还逐步拆分每一层的功能,顺带添加package包 Trump.Domain ...

  3. Spring Boot学习笔记(七)多数据源下的事务管理

    DataBaseConfig中加入事务管理器 DataBaseConfig的详解以及多数据源的配置参见我的上一篇文章 @Configuration @MapperScan(basePackages={ ...

  4. PHP trick(代码审计关注点)

    随着代码安全的普及,越来越多的开发人员知道了如何防御sqli.xss等与语言无关的漏洞,但是对于和开发语言本身相关的一些漏洞和缺陷却知之甚少,于是这些点也就是我们在Code audit的时候的重点关注 ...

  5. MVC 设计模式概述

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/53292312) 1.MVC设计模式: 如图所示,MVC模式(Mod ...

  6. SAP FI/CO 基本概念

    每一个SAP从业者都对这些概念不陌生,理解透了这些概念,对SAP的业务体系构架才能有明确地认识. 1.集团(client)的概念:是SAP中的最高等级:每一个集团建立主数据库. 2.公司(Compan ...

  7. Maven学习(五)使用Maven构建多模块项目

    使用Maven构建多模块项目 一般的web项目构成: 建立解决方案目录parent 首先使用命令进入到我们需要建立maven项目的目录: mvn archetype:generate -DgroupI ...

  8. MySql 利用crontab实现MySql定时任务

    MySql 利用crontab实现MySql定时任务 by:授客 QQ:1033553122 适用平台 任意myslq版本数据库 操作方法 登陆到数据库系统所在的linxu系统 第一步:新建名为cro ...

  9. .net4.0多进程间共享内存实现通信(VB.Net)

    .net4.0新增内存共享功能,从而很方便的实现了多进程间通信. 源码下载

  10. Mac下使用VScode进行C/C++开发

    1.安装 从VScode官网下载Mac系统适用的VScode安装包,下载完成后,将zip安装包解压到桌面即可. 2.插件安装 实现 C/Cpp 代码自动补全,函数跳转. 打开VScode后,按下组合键 ...