转载

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. grammar_action

    w ll = [] for i in range(0, 10, 1): ll.append(i) print(ll) for i in ll: if i < 6: print(i) index_ ...

  2. 网络流强化-POJ2516

    k种货物分开求解最小费用最大流,主要减少了寻找最短路的时间. #include<queue> #include<cstdio> #include<cstring> ...

  3. 查看mysql 的版本信息

    在进入mysql的情况下 在终端的情况下:

  4. 身份证验证的js

    function isIdCardNo(num) { num = num.toUpperCase(); //身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能 ...

  5. MySQL-极恶安装

    1.官网下载地址:https://dev.mysql.com/downloads/mysql/ 2.安装包下载后解压,并创建my.ini配置文件 内容如下,注意两个第三个#:MySQL的安装目录,第四 ...

  6. 洛谷P1168 中位数——set/线段树

    先上一波链接 https://www.luogu.com.cn/problem/P1168 这道题我们有两种写法 第一种呢是线段树,我们首先需要将原本的数据离散化,线段树维护的信息就是区间内有多少个数 ...

  7. 严重: StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException: Error creating bean with name

    HTTP Status 500 - Servlet.init() for servlet mybatis threw exception type Exception report message S ...

  8. java_第一年_JDBC(4)

    注:该篇只是为了小白的我熟悉下JDBC的代码,练习篇 在mysql中建test测试库,并创建一张employees表,加入一些数据如下图: 通过JDBC连接对表中数据进行添加: package lzj ...

  9. python面试题之Python如何实现单例模式?

    #使用__metaclass__(元类)的高级python用法 class Singleton2(type): def __init__(cls, name, bases, dict): super( ...

  10. 三种分布式锁 简易说说(包含前一篇提到的redis分布式锁)

    大多数互联网系统都是分布式部署的,分布式部署确实能带来性能和效率上的提升,但为此,我们就需要多解决一个分布式环境下,数据一致性的问题. 当某个资源在多系统之间,具有共享性的时候,为了保证大家访问这个资 ...