【BZOJ1458】【洛谷4311】士兵占领(网络流)
【BZOJ1458】【洛谷4311】士兵占领(网络流)
题面
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
题解
网络流一般就两种:最大流和最小割
这题很显然不是最小割。
所以就是最大流啦。。。
最大流既然是最大,题目要求的却是最小
所以就是求最大能够拿走多少个
于是,把行和列拆开
计算一下每一行最多能够拿走多少个,然后源点向它连边,容量就是最多能够拿走的个数。
每一列同理。
求最大流就行了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 222
#define INF 1000000000
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next,w;}e[MAX*MAX*5];
int h[MAX],cnt=2;
inline void Add(int u,int v,int w)
{
e[cnt]=(Line){v,h[u],w};h[u]=cnt++;
e[cnt]=(Line){u,h[v],0};h[v]=cnt++;
}
int level[MAX],S,T;
bool bfs()
{
memset(level,0,sizeof(level));level[S]=1;
queue<int> Q;Q.push(S);
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=h[u];i;i=e[i].next)
if(e[i].w&&!level[e[i].v])
level[e[i].v]=level[u]+1,Q.push(e[i].v);
}
return level[T];
}
int dfs(int u,int flow)
{
if(u==T||!flow)return flow;
int ret=0;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(e[i].w&&level[v]==level[u]+1)
{
int d=dfs(v,min(flow,e[i].w));
flow-=d;ret+=d;
e[i].w-=d;e[i^1].w+=d;
}
}
if(!ret)level[u]=0;
return ret;
}
int Dinic()
{
int ret=0;
while(bfs())ret+=dfs(S,INF);
return ret;
}
int n,m,K,L[MAX],R[MAX];
int g[MAX][MAX],Tx[MAX],Ty[MAX];
int main()
{
n=read();m=read();K=read();
for(int i=1;i<=n;++i)L[i]=read();
for(int i=1;i<=m;++i)R[i]=read();
for(int i=1;i<=K;++i)
{
int x=read(),y=read();
g[x][y]=1;
Tx[x]++;Ty[y]++;
}
for(int i=1;i<=n;++i)if(Tx[i]+L[i]>m){puts("JOING!");return 0;}
for(int i=1;i<=m;++i)if(Ty[i]+R[i]>n){puts("JOING!");return 0;}
S=0;T=n+m+1;
for(int i=1;i<=n;++i)Add(S,i,m-Tx[i]-L[i]);
for(int i=1;i<=m;++i)Add(i+n,T,n-Ty[i]-R[i]);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(!g[i][j])Add(i,j+n,1);
printf("%d\n",n*m-K-Dinic());
return 0;
}
【BZOJ1458】【洛谷4311】士兵占领(网络流)的更多相关文章
- 洛谷P4311 士兵占领
题目描述 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵 ...
- BZOJ1458 士兵占领 网络流 最大流 SAP
原文链接http://www.cnblogs.com/zhouzhendong/p/8384699.html 题目传送门 - BZOJ1458 题意概括 有一个M * N的棋盘,有的格子是障碍.现在你 ...
- BZOJ 1458: 士兵占领( 网络流 )
先判无解 把整个棋盘都放上士兵, 只需求最多可以拿走多少个士兵即可.每一行看做一个点r(i), 每一列看做一个点c(i) S->r(i), c(i)->T 连边, 容量为可以拿走的最大士兵 ...
- bzoj1458: 士兵占领 网络流
链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1458 也可以去luogu 思路 想成倒着删去点,使得依旧满足覆盖!! 左边横,右边列,之间用 ...
- 洛谷P1889 士兵站队
题目描述 在一个划分成网格的操场上, n个士兵散乱地站在网格点上.由整数 坐标 (x,y) 表示.士兵们可以沿网格边上.下左右移动一步,但在同时刻任一网格点上只能有名士兵.按照军官的命令,们要整齐地列 ...
- 洛谷P1251 餐巾(网络流)
P1251 餐巾 15通过 95提交 题目提供者该用户不存在 标签网络流贪心 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 为什么我全部10个测试点都对… 题目描述 一个餐厅在相继的N天里 ...
- 洛谷 P1889 士兵站队
P1889 士兵站队 题目描述 在一个划分成网格的操场上, n个士兵散乱地站在网格点上.由整数 坐标 (x,y) 表示.士兵们可以沿网格边上.下左右移动一步,但在同时刻任一网格点上只能有名士兵.按照军 ...
- 洛谷$P4177\ [CEOI2008]\ order$ 网络流
正解:网络流 解题报告: 传送门$QwQ$ 开始看感$jio$长得好像和太空飞行计划差不多的,,,然后仔细康康发现还有租操作,,, 按一般的套路碰到这样儿的一般就先按非特殊化的建图然后考虑怎么实现这个 ...
- 洛谷$P2050\ [NOI2012]$美食节 网络流
正解:网络流 解题报告: 传送门$QwQ$ 昂开始看到$jio$得,哇长得好像上一题嗷$QwQ$ 然后仔细康康数据范围,发现,哇好像要几万个点,,,显然就$GG$了 但感$jio$思路方向好对的亚子? ...
随机推荐
- idea 新建 maven项目遇到的一些问题
idea创建好了maven项目之后,需要先在项目中添加 Web,这里创建Web时就会要求fix一个Artifacts,新建即可,然后面板设置默认即可(shift+ctrl+alt+s 打开面板): 然 ...
- vue异步分页+初始化页面
html代码: <section class="container page-home"> <div id="main-content" cl ...
- JavaFX 学习笔记——jfoenix类库学习——raised风格按钮创建
创建按钮 JFXButton jfxb = new JFXButton("hello"); jfxb.getStyleClass().add("button-raised ...
- Query类型_JDBC的方法_JAVA方法_Loadrunner脚本
数据库查询压力测试脚本 jdbc_java_查询类型接口测试 package com.test; import java.sql.Connection; import java.sql.DriverM ...
- cs231n学习笔记(一)计算机视觉及其发展史
在网易云课堂上学习计算机视觉经典课程cs231n,觉得有必要做个笔记,因为自己的记性比较差,留待以后查看. 每一堂课都对应一个学习笔记,下面就开始第一堂课. 这堂课主要是回顾了计算机视觉的起源及其后来 ...
- python基础知识-7-内存、深浅、文件操作
python其他知识目录 1.一些对内存深入理解的案例 以下列举列表,列表/字典/集合这些可变类型都是一样的原理 变量是个地址,指向存储数据的内存空间的地址,它的实质就相当于c语言里的指针.变量和数据 ...
- 复利计算器app发布
复利计算器app发布 抱歉:由于无法实现服务端的持续开启,发布的app仅为简单的单机版,暂时舍弃了c/s版本的一些功能,如:投资动态管理功能. 应用详情博客:请点击这里 apk下载地址1(百度手机助手 ...
- Java 通过先序中序序列生成二叉树
题目 二叉树的前序以及后续序列,以空格间隔每个元素,重构二叉树,最后输出二叉树的三种遍历方式的序列以验证. 输入: 1 2 3 4 5 6 7 8 9 10 3 2 5 4 1 7 8 6 10 9 ...
- android入门 — Activity启动模式
1.standard模式 standard模式是系统的默认启动方式,每次激活Activity都会创建Activity,并放在任务栈中. 系统不会在乎活动是否已经存在于返回栈中,每次启动都会创建该活动的 ...
- DNS测试工具的使用(了解)
dig命令, host命令, nslookup命令,rndc命令 dig命令(直接测试DNS性能,不会查询/etc/hosts文件) dig [-t RR_TYPE] name [@SERVER] [ ...