转载

http://hzwer.com/2963.html

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

题解

此题的思路是先放满棋盘,然后考虑最多可以删多少个。。。

某一行和某一列的可以放的格子数小于需求就直接jiong掉
然后从源向每一行连边,流量为可以放的格子数 – 需求的格子数(也就是可以删多少格子)
从每一列向汇,同上.
从每一个非障碍的格子的行向列连边流量为1
跑一遍最大流即可ans=可放格子数-maxflow

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define T 201
#define inf 0x7fffffff
inline int read()
{
char ch=getchar();
int f=,x=;
while(!(ch>=''&&ch<='')){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+(ch-'');ch=getchar();}
return x*f;
}
using namespace std;
int n,m,K,cnt=,tot,ans;
int l[],c[],a[],b[];
bool mp[][];
int q[],h[],head[],cur[];
struct data{int to,next,v;}e[];
void ins(int u,int v,int w)
{e[++cnt].to=v;e[cnt].next=head[u];e[cnt].v=w;head[u]=cnt;}
void insert(int u,int v,int w)
{ins(u,v,w);ins(v,u,);}
bool bfs()
{
int t=,w=;
for(int i=;i<=T;i++)h[i]=-;
q[]=;h[]=;
while(t!=w)
{
int now=q[t];t++;
for(int i=head[now];i;i=e[i].next)
if(e[i].v&&h[e[i].to]==-)
{
h[e[i].to]=h[now]+;
q[w++]=e[i].to;
}
}
if(h[T]==-)return ;
return ;
}
int dfs(int x,int f)
{
if(x==T)return f;
int w,used=;
for(int i=cur[x];i;i=e[i].next)
{
if(e[i].v&&h[e[i].to]==h[x]+)
{
w=f-used;
w=dfs(e[i].to,min(e[i].v,w));
e[i].v-=w;
if(e[i].v)cur[x]=i;
e[i^].v+=w;
used+=w;if(used==f)return f;
}
}
if(!used)h[x]=-;
return used;
}
void dinic()
{while(bfs()){for(int i=;i<=T;i++)cur[i]=head[i];ans+=dfs(,inf);}}
int main()
{
m=read();n=read();K=read();
int x,y;
for(int i=;i<=m;i++)
l[i]=n-read();
for(int i=;i<=n;i++)
c[i]=m-read();
for(int i=;i<=K;i++)
{
x=read();y=read();
mp[x][y]=;
a[x]++;b[y]++;
if(a[x]>l[x]){printf("JIONG!");return ;}
if(b[y]>c[y]){printf("JIONG!");return ;}
}
tot=n*m-K;
for(int i=;i<=m;i++)
insert(,i,l[i]-a[i]);
for(int i=;i<=n;i++)
insert(m+i,T,c[i]-b[i]);
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
if(!mp[i][j])insert(i,j+m,);
dinic();
printf("%d",tot-ans);
return ;
}
 #include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <map> using namespace std;
typedef long long LL;
const int maxn = ;
const int maxm = ;
const int inf = <<; int n,m,K,S,T,cnt,ecnt=,ehead[maxn],du[maxn];
int g[maxm][maxm],row[maxn],col[maxn]; struct edge {
int u,v,vol,next;
}edg[maxn];
void add(int u,int v,int vol)
{
edg[++ecnt]=(edge){u,v,vol,ehead[u]};
ehead[u]=ecnt;
edg[++ecnt]=(edge){v,u,,ehead[v]};
ehead[v]=ecnt;
} namespace dinic
{
int lab[maxn],que[maxn],head,tail;
int dfs(int u,int cur,int T)
{
int res=;
if (u==T) return cur;
for (int v,j=ehead[u];j&&res<cur;j=edg[j].next)
if (edg[j].vol&&lab[v=edg[j].v]==lab[u]+) {
int tmp=dfs(v,min(cur-res,edg[j].vol),T);
edg[j].vol-=tmp;edg[j^].vol+=tmp;res+=tmp;
}
if (!res) lab[u]=-;
return res;
}
bool bfs(int S,int T)
{
memset(lab,-,sizeof(int)*(cnt+));
que[head=tail=]=S;lab[S]=;
while (head<=tail)
{
int u=que[head++];
for (int v,j=ehead[u];j;j=edg[j].next)
if (edg[j].vol&&lab[v=edg[j].v]==-)
{lab[v]=lab[u]+;que[++tail]=v;}
}
return lab[T]!=-;
}
int dinic(int S,int T)
{
int res=;
while (bfs(S,T)) res+=dfs(S,inf,T);
return res;
}
int main()
{
int sS=++cnt,sT=++cnt;
int ocnt=ecnt;
for (int i=;i<sS;i++)
{
if (du[i]>) add(i,sT,du[i]);
if (du[i]<) add(sS,i,-du[i]);
}
add(T,S,inf);dinic(sS,sT);
int res=edg[ecnt].vol;
for (int j=ehead[sS];j;j=edg[j].next)
if (edg[j].vol) return -;
for (int j=ocnt+;j<=ecnt;j++)
edg[j].vol=;
return res-dinic(T,S); }
}
int main()
{
scanf("%d %d %d",&n,&m,&K);
S=++cnt;T=++cnt;
for (int i=;i<=n;i++) row[i]=++cnt;
for (int i=;i<=m;i++) col[i]=++cnt;
for (int x,i=;i<=n;i++)
scanf("%d",&x),du[row[i]]-=x,du[S]+=x,add(S,row[i],m);
for (int x,i=;i<=m;i++)
scanf("%d",&x),du[col[i]]+=x,du[T]-=x,add(col[i],T,n);
for (int u,v,i=;i<=K;i++)
scanf("%d %d",&u,&v),g[u][v]=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (!g[i][j]) add(row[i],col[j],);
int ans=dinic::main();
if (ans!=-) printf("%d",ans);else puts("No Solution");
return ;
}

【bzoj1458】士兵占领(最大流||有源汇最大流)的更多相关文章

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

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

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

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

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

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

  4. bzoj1458士兵占领

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

  5. Cogs 12. 运输问题2(有上下界的有源汇最大流)

    运输问题2 ★★☆ 输入文件:maxflowb.in 输出文件:maxflowb.out 简单对比 时间限制:1 s 内存限制:128 MB 运输问题 [问题描述] 一个工厂每天生产若干商品,需运输到 ...

  6. zoj3229 Shoot the Bullet (有源汇最大流)

    题目大意:文文要给幻想乡的女♂孩子们拍照,一共n天,m个女♂孩子,每天文文至多拍D[i]张照片,每个女♂孩子总共要被文文至少拍G[i]次.在第i天,文文可以拍c[i]个女♂孩子,c[i]个女♂孩子中每 ...

  7. ZOJ 3229 Shoot the Bullet | 有源汇可行流

    题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...

  8. [BZOJ3698]XWW的难题解题报告|上下界网络流|有源汇最大流

    XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核.XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XW ...

  9. SGU 176 (有源汇最小流)

    转载:http://blog.csdn.net/dan__ge/article/details/51207951 题意:n个节点,m条路径,接下来m行a,b,c,d,如果d等于1,则a到b的流量必须为 ...

随机推荐

  1. EZOJ #375高速公路

    分析 我们可以先跑一遍全价的最短路 之后我们枚举这个第k大的价格w[i] 将其它边减这个边的权值和0取max 在跑出最短路之后加上减去的费用,即w[i]*k 我们发现如果价值大于w[i]的边小于k个 ...

  2. 理解JavaScript中的this

    在JavaScript中,this关键字是用来引用 调用该函数的 那个对象的.看几个栗子: var name="Window"; var obj={ name:"Obje ...

  3. Convolutional Neural Networks(2):Sparse Interactions, Receptive Field and Parameter Sharing

    Sparse Interactions, Receptive Field and Parameter Sharing是整个CNN深度网络的核心部分,我们用本文来具体分析其原理. 首先我们考虑Feedf ...

  4. Vulhub搭建

    Vulhub是一个比较全面的漏洞集合,收集了近年来许多的重要漏洞,以开源的形式呈现,以docker的形式进行环境配置,提供了更简单的漏洞复现,只需要简单的命令即可实现漏洞复现. 官网  https:/ ...

  5. mybatise根据list参数查询

    where id in<foreach item="item" index="index" collection="map.idList&quo ...

  6. Arrays工具类使用与源码分析(1)

    Arrays工具类主要是方便数组操作的,学习好该类可以让我们在编程过程中轻松解决数组相关的问题,简化代码的开发. Arrays类有一个私有的构造函数,没有对外提供实例化的方法,因此无法实例化对象.因为 ...

  7. [Linux] 004 安装

    1. 安装欢迎界面 Install or upgrade an existing system 安装或升级现有系统 Install system with basic video driver 安装过 ...

  8. shell编程:awk基础

    语法格式: 一 awk 'BEGIN{}pattern{commands}END{}' file_name 二 standard output | awk 'BEGIN{}pattern{comman ...

  9. Linux访问一个url

    命令一:wget(直接把url的内容下载下来) [root@localhost ~]# wget www.baidu.com--2018-06-16 21:23:49-- http://www.bai ...

  10. 2019 Multi-University Training Contest 1 - 1012 - NTT

    题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=6589 题解连接: https://www.cnblogs.com/xusirui/p/1122945 ...