【bzoj1458】士兵占领(最大流||有源汇最大流)
转载
http://hzwer.com/2963.html
Description
Input
Output
Sample Input
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3
Sample Output
数据范围
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】士兵占领(最大流||有源汇最大流)的更多相关文章
- BZOJ1458:士兵占领(有上下界最小流)
Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放 ...
- bzoj1458: 士兵占领(最大流)
题目描述 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵 ...
- BZOJ1458 士兵占领 网络流 最大流 SAP
原文链接http://www.cnblogs.com/zhouzhendong/p/8384699.html 题目传送门 - BZOJ1458 题意概括 有一个M * N的棋盘,有的格子是障碍.现在你 ...
- bzoj1458士兵占领
传送门 和上一题差不多,每行和每列分别看做一个点,障碍点坐标的行和列就不建边,再按照有源汇上下界建图就好了,唯一的区别就是这个题求的是最小流 这个题的数据好水呢,建错图也能A呢 #include< ...
- Cogs 12. 运输问题2(有上下界的有源汇最大流)
运输问题2 ★★☆ 输入文件:maxflowb.in 输出文件:maxflowb.out 简单对比 时间限制:1 s 内存限制:128 MB 运输问题 [问题描述] 一个工厂每天生产若干商品,需运输到 ...
- zoj3229 Shoot the Bullet (有源汇最大流)
题目大意:文文要给幻想乡的女♂孩子们拍照,一共n天,m个女♂孩子,每天文文至多拍D[i]张照片,每个女♂孩子总共要被文文至少拍G[i]次.在第i天,文文可以拍c[i]个女♂孩子,c[i]个女♂孩子中每 ...
- ZOJ 3229 Shoot the Bullet | 有源汇可行流
题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...
- [BZOJ3698]XWW的难题解题报告|上下界网络流|有源汇最大流
XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核.XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A,满足XW ...
- SGU 176 (有源汇最小流)
转载:http://blog.csdn.net/dan__ge/article/details/51207951 题意:n个节点,m条路径,接下来m行a,b,c,d,如果d等于1,则a到b的流量必须为 ...
随机推荐
- leetcode 235. 二叉搜索树的最近公共祖先(c++)
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x ...
- 【BASIS系列】SAP 设置系统timeout时间
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BASIS系列]SAP 设置系统timeout ...
- mysql - 标识列
#标识列 /* 又称为自增长列 含义:可以不用手动插入值,系统提供默认的序列值 特点: 1.表示列必须和主键搭配吗?不一定,但是要求是一个key 2.一个表中只能有一个标识列! 3.标识列的类型有限制 ...
- 安全体系建设-OWASP
OWASP Checklist Spiders, Robots and Crawlers IG- Search Engine Discovery/Reconnaissance IG- Identify ...
- Codeforces Round #410 (Div. 2)B. Mike and strings(暴力)
传送门 Description Mike has n strings s1, s2, ..., sn each consisting of lowercase English letters. In ...
- System.Web.Script.Serialization的引用
解决方案: 找到C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0 ==>System.Web.Extensions.d ...
- is_numeric漏洞总结
将16进制数据判断为数据,这样在存入数据库后,数据库会把16进制解析成字符串,可能造成二次注入 转载: https://www.jianshu.com/p/e7cf997d6ccb
- JAVA线程初体验
线程的创建 线程的启动和停止 /** * 演员类 继承Thread类 * @author Administrator * */ public class Actor extends Thread { ...
- #python# error:urllib.error.URLError: <urlopen error [Errno 11001] getaddrinfo failed>
设置代理后访问网页报错,百度有人说地址拼写不对,确认拼写后依然报错 因为使用的是xici免费代理,想到可能代理不可用造成getaddrinfo failed, 更换其他代理,error消失
- G a+b+c+d=?
G a+b+c+d=? 链接:https://ac.nowcoder.com/acm/contest/338/G来源:牛客网 题目描述 This is a very simple problem! Y ...