[SCOI2007] 蜥蜴 (最大流)
[SCOI2007] 蜥蜴
题目背景
07四川省选
题目描述
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。
每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。
输入输出格式
输入格式:
输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石柱的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。
输出格式:
输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。
输入输出样例
输入样例#1:
5 8 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
输出样例#1:
1
说明
100%的数据满足:\(1<=r, c<=20, 1<=d<=4\)
Solution
看到题目中的柱子每经过一次高度-1马上想到网络流,每根柱子的高度就是网络中一条边的容量
其实网络流的题目一般就是考建边,建完以后套个最大流模板就行了
那么怎么建边呢?
建一个源点S,汇点T(都是虚点)
- 考虑拆点,我们把一个柱子拆成入点和出点,把这两个点之间建一条容量为柱子高度x的边,代表这棵柱子最多只能经过x次
- 对于能够到达地图外的点,我们之间从它的出点向汇点建一条容量为inf的边
- 枚举两个柱子,在地图上欧几里得距离小于最大跳跃距离的点之间建一条容量为inf的边
- 由源点向每个蜥蜴所在的点建一条容量为1的边,代表这个点有一个蜥蜴
Code
#include<bits/stdc++.h>
#define rg register
#define il inline
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)
#define dis(a,b,x,y) ((x-a)*(x-a)+(y-b)*(y-b))
using namespace std;
const int N=100,M=1e6+10;
const int inf=2e9;
void in(int &ans) {
ans=0; char i=getchar();
while(i<'0' || i>'9') i=getchar();
while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();
}
int n,m,d,cur=1,ans;
int S,T,NN,c1,c2,sum;
char ch;
int to[M<<1],nex[M<<1],head[M],cap[M<<1],lev[M],curr[M];
int c[N][N],p[N][N];
int l[M<<1],r[M<<1];
struct node {
int l,r;
};
vector<node>v;
il void add(int a,int b,int c) {
to[++cur]=b,nex[cur]=head[a];
cap[cur]=c,head[a]=cur;
}
il void read() {
NN=n*m; T=2*n*m+1;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
cin>>ch; p[i][j]=++c1;
c[i][j]=ch-'0';
if(c[i][j]) l[++c2]=i,r[c2]=j;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
cin>>ch; if(ch=='L') sum++,v.push_back((node){i,j});
}
}
il void init() {
for(int i=1;i<=c2;i++) {
add(p[l[i]][r[i]],p[l[i]][r[i]]+NN,c[l[i]][r[i]]);
add(p[l[i]][r[i]]+NN,p[l[i]][r[i]],0);
if(l[i]<=d || r[i]<=d || l[i]+d>n || r[i]+d>m) {
add(p[l[i]][r[i]]+NN,T,inf);
add(T,p[l[i]][r[i]]+NN,0);
}
}
for(int i=1;i<=c2;i++)
for(int j=1;j<=c2;j++) {
if(dis(l[i],r[i],l[j],r[j])<=d*d && i!=j) {
add(p[l[i]][r[i]]+NN,p[l[j]][r[j]],inf);
add(p[l[j]][r[j]],p[l[i]][r[i]]+NN,0);
}
}
for(int i=0;i<sum;i++) {
add(S,p[v[i].l][v[i].r],1);
add(p[v[i].l][v[i].r],S,0);
}
}
bool bfs(int s,int t) {
queue<int>q; memset(lev,-1,sizeof(lev));
q.push(s); lev[s]=0;
while(!q.empty()) {
int u=q.front(); q.pop();
for(int i=head[u];i;i=nex[i]) {
if(lev[to[i]]==-1 && cap[i]>0) {
lev[to[i]]=lev[u]+1;
q.push(to[i]);
}
}
}
return lev[t]!=-1;
}
int dfs(int s,int f,int t,int rest=0) {
if(s==t) return f;
for(int i=head[s];i;i=nex[i]) {
if(lev[to[i]]==lev[s]+1 && cap[i]>0) {
int r=dfs(to[i],Min(cap[i],f-rest),t);
if(r>0) rest+=r,cap[i]-=r,cap[i^1]+=r;
}
}
if(!rest) lev[s]=-1;
return rest;
}
int main()
{
in(n),in(m),in(d);
read(); init();
while(bfs(S,T))
while(int c=dfs(S,inf,T)) ans+=c;
printf("%d\n",sum-ans);
return 0;
}
博主蒟蒻,随意转载.但必须附上原文链接
http://www.cnblogs.com/real-l/
[SCOI2007] 蜥蜴 (最大流)的更多相关文章
- P2472 [SCOI2007]蜥蜴 (最大流)
题目 P2472 [SCOI2007]蜥蜴 解析 这个题思路比较清晰,本(qi)来(shi)以(jiu)为(shi)无脑建图跑最大流,结果挂了,整了一个小时后重新建图才过的. 建立一个超级源点和一个超 ...
- BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )
结点容量..拆点然后随便写 --------------------------------------------------------------- #include<cstdio> ...
- poj 2711 Leapin' Lizards && BZOJ 1066: [SCOI2007]蜥蜴 最大流
题目链接:http://poj.org/problem?id=2711 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1066 Your p ...
- 【bzoj1066】[SCOI2007]蜥蜴 网络最大流
[bzoj1066][SCOI2007]蜥蜴 Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的 ...
- POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)
POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...
- P2472 [SCOI2007]蜥蜴(网络最大流)
P2472 [SCOI2007]蜥蜴 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距 ...
- BZOJ1066 SCOI2007 蜥蜴 【网络流-最大流】
BZOJ1066 SCOI2007 蜥蜴 Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离 ...
- bzoj1066: [SCOI2007]蜥蜴(最大流)
1066: [SCOI2007]蜥蜴 题目:传送门 题解: 哇QTT大佬一眼秒算法...ORT 其实很容易就可以看出来是一道最大流 因为有边的使用限制,那么就可以直接当成是流量来处理嘛 因为是对点进行 ...
- P2472 [SCOI2007]蜥蜴(最大流)
P2472 [SCOI2007]蜥蜴 自己第一道独立做题且一遍AC的网络流题纪念... 看到这道题我就想到网络流建图的方式了... 首先根据每个高度,我们将每个点拆成两个点限流.之后根据跳的最大距离, ...
随机推荐
- 11 非阻塞套接字与IO多路复用(进阶)
1.非阻塞套接字 第一部分 基本IO模型 1.普通套接字实现的服务端的缺陷 一次只能服务一个客户端! 2.普通套接字实现的服务端的瓶颈!!! accept阻塞! 在没有新的套接字来之前,不能处理已经建 ...
- 2.从print到自省
print是一个函数 为什么print是一个函数呢?可以在交互式解释器下 输入: >>> type(print) 输出: <class 'builtin_function_ ...
- Fabric go sdk初始化所需证书解析
fabric sdk go 提供的官方文档少之又少,要想入门,主要就靠研究官方的e2e系列示例,这真的是一件挺无奈的事情.没法子,只能硬着头皮上了.研究发现,e2e这个例子是通过cryptogen生成 ...
- 【EXCEL】SUMIF(条件を指定して数値を合計する)
Mirocrosoft Excel
- 怎么实现hibernate悲观锁和乐观锁?
隔离级别的安全控制是整体一个大的方面,而锁机制更加的灵活,它执行的粒度可以很小,可以在一个事务中存在. Hibernate悲观锁是依靠底层数据库的锁机制实现,在查询query.setLockMode( ...
- ASP.NET MVC5.0 OutputCache不起效果
按照官网文档(https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing ...
- linux备忘录-shell脚本
知识 shell执行方式 shell执行方式有 通过source或. 在现在的bash环境中执行脚本 变量等会保持 通过bash shell.sh或sh shell.sh 使用一个新的bash环境执行 ...
- 简单java采集程序一
[目标任务]通过该网站采集全国的手机号码段至数据库表中 [完成过程] 1.初涉正则表达式,学会写简单的正则表达式 2.获取单个网页内容,学会java中基本的IO流 3.将获取数据插入mysql数据库表 ...
- Linux 进程,线程,线程池
在linux内核,线程与进程的区别很小,或者说内核并没有真正所谓单独的线程的概念,进程的创建函数是fork,而线程的创建是通过clone实现的. 而clone与fork都是调用do_fork(),差异 ...
- 编程练习:寻找发帖"水王"扩展问题二
回顾 在前面两篇文章已经实现了水王id出现次数超过一半,以及水王id出现次数刚好一半 分析 借助上面水王id出现次数刚好出现一半的分析,其实这里就是找出数组中出现次数前三的元素,具体的分析,见前面两篇 ...