BZOJ 1458 士兵占领
http://www.lydsy.com/JudgeOnline/problem.php?id=1458
题意:n x m的棋盘,k个位置不能放,每行和每列都有要求至少的士兵,求能否有最少的满足条件的士兵放法是多少。
思路:先全放满求能否满足,再尽量删掉士兵:
对于每行:能放m[i],至少放c[i],就从S连向i:m[i]-c[i],代表能删的最大
对于每列:能放m[i],至少放c[i],就从i+n连向T:m[i]-c[i],代表能删的最大
这样对于i,j这个位置如果可以放士兵,那就从i行连向j+n,流量为1,共享删掉1个
求最大流,就等于最小割,得到的就是能删的最多,然后答案就是Σm1[i]-最大流
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define inf 0x7fffffff
int tot,go[],next[],flow[],first[];
int op[],nodes,T,S,dis[],cnt[],pd[][],n,m,k;
int m1[],m2[],c1[],c2[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y,int z){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
flow[tot]=z;
}
void add(int x,int y,int z){
insert(x,y,z);op[tot]=tot+;
insert(y,x,);op[tot]=tot-;
}
int dfs(int x,int f){
if (x==T) return f;
int mn=nodes,sum=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (flow[i]&&dis[pur]+==dis[x]){
int save=dfs(pur,std::min(f-sum,flow[i]));
flow[i]-=save;
flow[op[i]]+=save;
sum+=save;
if (sum==f||dis[S]>=nodes) return sum;
}
if (flow[i]) mn=std::min(mn,dis[pur]);
}
if (sum==){
cnt[dis[x]]--;
if (cnt[dis[x]]==){
dis[S]=nodes;
}else{
dis[x]=mn+;
cnt[dis[x]]++;
}
}
return sum;
}
int main(){
n=read();m=read();k=read();
S=,T=n+m+;nodes=T+;
int sum1=,sum2=;
for (int i=;i<=n;i++){
int x=read();
sum1+=x;
m1[i]=x;
}
for (int i=;i<=m;i++){
int x=read();
sum2+=x;
m2[i]=x;
}
for (int i=;i<=k;i++){
int x=read(),y=read();
pd[x][y]=;
}
int ans=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (!pd[i][j])
c1[i]++,c2[j]++;
int sx=;
for (int i=;i<=n;i++)
sx+=c1[i];
for (int i=;i<=n;i++)
if (c1[i]<m1[i]) {
printf("JIONG!\n");return ;
}
for (int i=;i<=m;i++)
if (c2[i]<m2[i]){
printf("JIONG!\n");return ;
}
for (int i=;i<=n;i++)
add(S,i,c1[i]-m1[i]);
for (int i=;i<=m;i++)
add(i+n,T,c2[i]-m2[i]);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (!pd[i][j])
add(i,j+n,);
while (dis[S]<nodes) ans+=dfs(S,inf);
ans=sx-ans;
printf("%d\n",ans);
}
BZOJ 1458 士兵占领的更多相关文章
- BZOJ 1458: 士兵占领( 网络流 )
先判无解 把整个棋盘都放上士兵, 只需求最多可以拿走多少个士兵即可.每一行看做一个点r(i), 每一列看做一个点c(i) S->r(i), c(i)->T 连边, 容量为可以拿走的最大士兵 ...
- bzoj 1458: 士兵占领 -- 最大流
1458: 士兵占领 Time Limit: 10 Sec Memory Limit: 64 MB Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵 ...
- 【刷题】BZOJ 1458 士兵占领
Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...
- bzoj 1458 士兵占领(最大流)
[题意] n行m列,第i行必须放L[i],第j列必须放C[j],有障碍格,求满足条件至少需要放多少. [思路] 至少放多少等价于最多不放多少. 对行列分别建XY点,则连边(S,Xi,a)(Yi,T,b ...
- 【BZOJ】1458: 士兵占领(上下界网络流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1458 是不是我脑洞太小了.......直接弄上下界最小流........(就当复习了.. 二分图X和 ...
- 1458: 士兵占领 - BZOJ
Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...
- 【BZOJ-1458】士兵占领 最大流
1458: 士兵占领 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 782 Solved: 456[Submit][Status][Discuss] ...
- 【BZOJ1458】【洛谷4311】士兵占领(网络流)
[BZOJ1458][洛谷4311]士兵占领(网络流) 题面 BZOJ权限题,洛谷真好 Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最 ...
- 【bzoj1458】士兵占领
Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...
随机推荐
- Android使用xml中定义的动画效果
Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.zqrl_out); animation.setFil ...
- cf B. Color the Fence
http://codeforces.com/contest/349/problem/B 贪心 #include <cstdio> #include <cstring> #inc ...
- Find the Duplicate Number 解答
Question Given an array nums containing n + 1 integers where each integer is between 1 and n (inclus ...
- Swap Nodes in Pairs 解答
Question Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1 ...
- 【HDU1232】畅通工程(并查集基础题)
裸敲并查集,很水一次AC #include <iostream> #include <cstring> #include <cstdlib> #include &l ...
- IT技术如何转向销售创业
广州 IT 网友 14:14:10 本人本科软件工程毕业,现在在一家公司做开发(不是很技术的那种),工作接近两年感觉自 己不适合这个行业,想换销售行业,不愿意在做技术.打算从事本行业的销售,老师给点 ...
- PHP批量审核后台
/*批量审核方法*/ function setOn_all() { if($_POST) { $p=M('news'); $data=array(); $i=0; foreach ($_POST as ...
- OpenStack中给wsgi程序写单元測试的方法
在 OpenStack 中, 针对web应用, 有三种方法来写单元測试 1) 使用webob生成模拟的request from __future__ import print_function imp ...
- MATLAB快速注释方法
觉得有用,未免以后忘记,收藏了.原文来自:http://i.azpala.com/2008/09/18/matlab-multi-line-comment/ A. %{ 若干语句 %} B. 多行注释 ...
- Android的ADB工具使用
在SDK的Tools文件夹下包含着Android模拟器操作的重要命令ADB,ADB的全称为Android Debug Bridge,就是调试桥的作用,借助这个工具,我们可以管理设备或手机模拟器的状态 ...