1458: 士兵占领

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 782  Solved: 456
[Submit][Status][Discuss]

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

HINT

Source

Solution

仰慕黄学长....

把题目转化一下,使用最少的,转换成删去最多的,那么可用最大流求解

对于某行或某列,如果可以放的个数小于必须放的个数,那么直接JIONG!

那么对于源向各行连边,容量为可以放的格子数 – 需求的格子数

对于各列向汇连边,容量同上

从可放置的点的行连至列,容量为1

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxm 20000
#define maxn 500
int n,m,k;int L[],C[];
int zt[][];
int hang[],lie[],ans,tot,S,T;
struct Edgenode{int next,to,cap;}edge[maxm];
int head[maxn],cnt=;
void add(int u,int v,int w)
{cnt++;edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt;edge[cnt].cap=w;}
void insert(int u,int v,int w)
{add(u,v,w);add(v,u,);}
//
int q[maxn],dis[maxn],cur[maxn];
bool bfs()
{
for (int i=S; i<=T; i++) dis[i]=-;
int he=,ta=; q[]=S; dis[S]=;
while (he<ta)
{
int now=q[he++];
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==-)
{
dis[edge[i].to]=dis[now]+;
q[ta++]=edge[i].to;
}
}
return dis[T]!=-;
}
int dfs(int loc,int low)
{
if (loc==T) return low;
int w,used=;
for (int i=cur[loc]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==dis[loc]+)
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^].cap+=w;
used+=w; if (edge[i].cap) cur[loc]=i;
if (used==low) return low;
}
if (!used) dis[loc]=-;
return used;
}
#define inf 0x7fffffff
int dinic()
{
int tmp=;
while (bfs())
{
for (int i=S; i<=T; i++) cur[i]=head[i];
tmp+=dfs(S,inf);
}
return tmp;
}
void make()
{
S=,T=n+m+;
for (int i=; i<=m; i++)
insert(S,i,n-L[i]-hang[i]);
for (int i=; i<=n; i++)
insert(i+m,T,m-C[i]-lie[T]);
for (int i=; i<=m; i++)
for (int j=; j<=n; j++)
if (!zt[i][j]) insert(i,j+m,);
}
int main()
{
m=read(),n=read(),k=read();
for (int i=; i<=m; i++) L[i]=read();
for (int i=; i<=n; i++) C[i]=read();
tot=n*m-k;
for (int x,y,i=; i<=k; i++)
x=read(),y=read(),hang[x]++,lie[y]++,zt[x][y]=;
for (int i=; i<=m; i++)
if (hang[i]>n-L[i]) {puts("JIONG!");return ;}
for (int i=; i<=n; i++)
if (lie[i]>m-C[i]) {puts("JIONG!");return ;}
make();
ans=dinic();
printf("%d\n",tot-ans);
return ;
}

好厉害...一开始没想到...看到这种网格图,就想黑白染色QAQ

【BZOJ-1458】士兵占领 最大流的更多相关文章

  1. bzoj 1458: 士兵占领 -- 最大流

    1458: 士兵占领 Time Limit: 10 Sec  Memory Limit: 64 MB Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵 ...

  2. BZOJ 1458: 士兵占领( 网络流 )

    先判无解 把整个棋盘都放上士兵, 只需求最多可以拿走多少个士兵即可.每一行看做一个点r(i), 每一列看做一个点c(i) S->r(i), c(i)->T 连边, 容量为可以拿走的最大士兵 ...

  3. 【刷题】BZOJ 1458 士兵占领

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

  4. bzoj 1458 士兵占领(最大流)

    [题意] n行m列,第i行必须放L[i],第j列必须放C[j],有障碍格,求满足条件至少需要放多少. [思路] 至少放多少等价于最多不放多少. 对行列分别建XY点,则连边(S,Xi,a)(Yi,T,b ...

  5. BZOJ 1458 士兵占领

    http://www.lydsy.com/JudgeOnline/problem.php?id=1458 题意:n x m的棋盘,k个位置不能放,每行和每列都有要求至少的士兵,求能否有最少的满足条件的 ...

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

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

  7. 1458: 士兵占领 - BZOJ

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

  8. 【BZOJ1458】士兵占领 最小流

    [BZOJ1458]士兵占领 Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占 ...

  9. P4311 士兵占领[最大流]

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

随机推荐

  1. PHP命令行模式

    <?php error_reporting(E_ALL); header('Content-Type:text/plain;charset=utf-8'); interface CommandA ...

  2. 005商城项目:ssm框架的整合成功之后的问题:使用maven的tomcat插件时的debug

    在执行maven的clean时经常碰到一个问题: 解决: 然后: 还有一个问题是:用maven 使用Debug调试时,不能看到源代码. 解决办法: 下面选择Debug Configurations 这 ...

  3. centos6下安装dedecms

    几经波折,终于安装成功!!! 一.centos6下安装WDCP 1.连接linux 在百度直接搜索下载xshell,通过ssh连接 2.安装wdcp 下载安装wget http://dl.wdlinu ...

  4. Linux system函数详解

    system 功能:system()函数调用"/bin/sh -c command"执行特定的命令,阻塞当前进程直到command命令执行完毕 原型 int system(cons ...

  5. Linux 进程详解

    Linux内核的七大区间 .进程管理(进程创建,进程的三种状态,进程间的调度,调度算法...) .内存管理(段式管理(Linux所有段都从0开始),页式管理--地址偏移量) .系统调用(C语言库函数的 ...

  6. Openwrt Image Builder/SDK 初探

    image builder和SDK既可以从官网上下载,又可以自己进行编译(make menuconfig).官网上下载的是预先帮你编译好的,这样可以大量节省自己编译源码花的时间,这两个东西相当于半成品 ...

  7. WPF 绑定枚举值

    前台Xaml <ComboBox x:Name=" HorizontalAlignment="Left" Margin="5 0 0 0" Se ...

  8. 从idea上通过路径去导入项目

    这里我用git来演示导入. 首先确定你要导入项目的路径.(我这里用码云路径图片做演示) 1.选择 2.填写

  9. php基础入门

    一.序言 由于新公司的需要,我也就从原来的asp专向了,php的学习中.希望通过自己的学习能够尽快的熟悉了解php 二.php独特的语法特色  1.引号问题 在php中单引号和双引号的作用基本相同,但 ...

  10. [BZOJ3144][HNOI2013]切糕(最小割)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3144 分析:神题不解释 http://www.cnblogs.com/zig-zag/ ...