1458: 士兵占据

Time Limit: 10 Sec  Memory Limit: 64 MB

Submit: 685  Solved: 398

[Submit][Status][

id=1458" style="color:blue; text-decoration:none">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

有源汇有上下界最小流问题

将行抽象为左部点,列抽象为右部点。

假设某个位置没有障碍。就从行相应的节点到列相应的节点连边。下界为0,上界为1。

在从源点向每行相应的节点连边,从每列相应的节点向汇点连边,下界均为该行或列的最少士兵数。上界均为正无穷。

最后求s到t的最小流。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define pa pair<int,int>
#define maxn 300
#define maxm 100000
#define inf 1000000000
using namespace std;
int head[maxn],cur[maxn],dis[maxn],in[maxn];
int cnt=1,mx=0,maxflow,n,m,k,x,y,s,t,ss,tt;
bool a[105][105];
struct edge_type
{
int next,to,v;
}e[maxm];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void add_edge(int x,int y,int v)
{
e[++cnt]=(edge_type){head[x],y,v};head[x]=cnt;
e[++cnt]=(edge_type){head[y],x,0};head[y]=cnt;
}
inline void insert(int x,int y,int l,int r)
{
in[x]-=l;in[y]+=l;
if (r-l) add_edge(x,y,r-l);
}
inline void build()
{
F(i,1,tt)
{
if (in[i]>0) add_edge(ss,i,in[i]);
else if (in[i]<0) add_edge(i,tt,-in[i]);
}
}
inline bool bfs()
{
queue<int>q;
memset(dis,-1,sizeof(dis));
dis[s]=0;q.push(s);
while (!q.empty())
{
int tmp=q.front();q.pop();
if (tmp==t) return true;
for(int i=head[tmp];i;i=e[i].next) if (e[i].v&&dis[e[i].to]==-1)
{
dis[e[i].to]=dis[tmp]+1;
q.push(e[i].to);
}
}
return false;
}
inline int dfs(int x,int f)
{
if (x==t) return f;
int tmp,sum=0;
for(int &i=cur[x];i;i=e[i].next)
{
int y=e[i].to;
if (e[i].v&&dis[y]==dis[x]+1)
{
tmp=dfs(y,min(f-sum,e[i].v));
e[i].v-=tmp;e[i^1].v+=tmp;sum+=tmp;
if (sum==f) return sum;
}
}
if (!sum) dis[x]=-1;
return sum;
}
inline void dinic()
{
maxflow=0;
while (bfs())
{
F(i,1,tt) cur[i]=head[i];
maxflow+=dfs(s,inf);
}
}
inline void minflow()
{
s=ss;t=tt;
dinic();
int ans=e[cnt].v;
if (ans<mx)
{
printf("JIONG!\n");
return;
}
e[cnt].v=e[cnt^1].v=0;
s=n+m+2;t=n+m+1;
dinic();
printf("%d\n",ans-maxflow);
}
int main()
{
int tot=0;
m=read();n=read();k=read();
s=m+n+1;t=s+1;ss=t+1;tt=ss+1;
F(i,1,m){x=read();tot+=x;insert(s,i,x,inf);}
mx=max(mx,tot);
tot=0;
F(i,1,n){x=read();tot+=x;insert(i+m,t,x,inf);}
mx=max(mx,tot);
F(i,1,k)
{
x=read();y=read();
a[x][y]=true;
}
F(i,1,m) F(j,1,n) if (!a[i][j]) insert(i,j+m,0,1);
build();
add_edge(t,s,inf);
minflow();
}

bzoj1458 士兵占据的更多相关文章

  1. BZOJ1458 士兵占领 网络流 最大流 SAP

    原文链接http://www.cnblogs.com/zhouzhendong/p/8384699.html 题目传送门 - BZOJ1458 题意概括 有一个M * N的棋盘,有的格子是障碍.现在你 ...

  2. bzoj1458 士兵占领

    费用流,连下面几类边 1.s->s',流量为n*m,费用为0,表示最多可放置n*m个士兵 2.s'->行 (1)流量为a[i],费用为-n*m,表示必须在这一行放置a[i]个士兵. (2) ...

  3. BZOJ1458:士兵占领(有上下界最小流)

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

  4. BZOJ1458 士兵占领 【带上下界网络流】

    题目链接 BZOJ1458 题解 对行列分别建边,拆点,设置流量下限 然后\(S\)向行连边\(inf\),列向\(T\)连边\(inf\),行列之间如果没有障碍,就连边\(1\) 然后跑最小可行流即 ...

  5. bzoj1458: 士兵占领(最大流)

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

  6. bzoj1458: 士兵占领 网络流

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1458 也可以去luogu 思路 想成倒着删去点,使得依旧满足覆盖!! 左边横,右边列,之间用 ...

  7. bzoj1458士兵占领

    传送门 和上一题差不多,每行和每列分别看做一个点,障碍点坐标的行和列就不建边,再按照有源汇上下界建图就好了,唯一的区别就是这个题求的是最小流 这个题的数据好水呢,建错图也能A呢 #include< ...

  8. [NetworkFlow]网络流建模相关

    流 网络流问题本质上是线性规划问题的应用之中的一个,线性规划问题的标准形式是给出一组等式约束和不等式约束.要求最优化一个线性函数. 在流问题中,变量以流量的形式出如今问题中,我们给出一个流网络(以有向 ...

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

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

随机推荐

  1. 刷题总结——work(ssoj)

    题目: 题目背景 SOURCE:NOIP2015-SHY-5 题目描述 假设现在离 noip 还有 m 天,有 n 个人要去参加比赛.他们每个人都有一个预定的训练量 r[i] ,所以每一天他们都抓紧时 ...

  2. java面试题之@Autowired和@Resource的区别

    @Autowired和@Resource的区别: 1.都可以用来装配bean,都可以写在字段或者方法上: 2. @Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果允许为nul ...

  3. bzoj 5056: OI游戏 最短路树的计数

    OI游戏 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 196  Solved: 159[Submit][Status][Discuss] Descrip ...

  4. Perl语言入门--5--散列、hash

    hash 一.关联数组的形式 %h=('a',1,'b',2);         a是key 1是value    b是key  2是value 以%开头,()为空散列 %h=('a'=>1,' ...

  5. CSS3自定义滚动条

    webkit支持拥有overflow属性的区域,列表框,下拉菜单,textarea的滚动条自定义样式,不过由于用到了CSS3的属性,兼容性不好 看下滚动条demo:demo1(纯CSS3版) 滚动条的 ...

  6. python学习之-- 故障记录汇总

    以下为我编程期间遇到的错误并进行记录,起始时间2017-6-21 时间:2018/11/21问题现象:ajax 执行异步提交后,在访问日志看出现了2次post执行分析:默认ajax提交是执行一次,然后 ...

  7. 牛客网 牛客小白月赛1 A.简单题-控制输出格式setiosflags()函数+setprecision()函数

    水一水博客,都不好意思写这篇博客,毕竟已经不是大一的了. 难得能把一整套题都写出来(日常智障).但是在这里不写G题あなたの蛙は旅⽴っています的题解. 有毒,G题关了流同步只能过94%的样例,说我运行超 ...

  8. SPOJ 1825 Free tour II (树的点分治)

    题目链接 Free tour II 题意:有$N$个顶点的树,节点间有权值, 节点分为黑点和白点. 找一条最长路径使得 路径上黑点数量不超过K个 这是树的点分治比较基本的题,涉及树上启发式合并……仰望 ...

  9. 洛谷—— P1849 [USACO12MAR]拖拉机Tractor

    https://www.luogu.org/problemnew/show/P1849 题目描述 After a long day of work, Farmer John completely fo ...

  10. 洛谷——P1187 3D模型

    P1187 3D模型 题目描述 一座城市建立在规则的n×m网格上,并且网格均由1×1正方形构成.在每个网格上都可以有一个建筑,建筑由若干个1×1×1的立方体搭建而成(也就是所有建筑的底部都在同一平面上 ...