[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(都是虚点)

  1. 考虑拆点,我们把一个柱子拆成入点和出点,把这两个点之间建一条容量为柱子高度x的边,代表这棵柱子最多只能经过x次
  2. 对于能够到达地图外的点,我们之间从它的出点向汇点建一条容量为inf的边
  3. 枚举两个柱子,在地图上欧几里得距离小于最大跳跃距离的点之间建一条容量为inf的边
  4. 由源点向每个蜥蜴所在的点建一条容量为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] 蜥蜴 (最大流)的更多相关文章

  1. P2472 [SCOI2007]蜥蜴 (最大流)

    题目 P2472 [SCOI2007]蜥蜴 解析 这个题思路比较清晰,本(qi)来(shi)以(jiu)为(shi)无脑建图跑最大流,结果挂了,整了一个小时后重新建图才过的. 建立一个超级源点和一个超 ...

  2. BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )

    结点容量..拆点然后随便写 --------------------------------------------------------------- #include<cstdio> ...

  3. poj 2711 Leapin' Lizards && BZOJ 1066: [SCOI2007]蜥蜴 最大流

    题目链接:http://poj.org/problem?id=2711 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1066 Your p ...

  4. 【bzoj1066】[SCOI2007]蜥蜴 网络最大流

    [bzoj1066][SCOI2007]蜥蜴 Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的 ...

  5. POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)

    POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...

  6. P2472 [SCOI2007]蜥蜴(网络最大流)

    P2472 [SCOI2007]蜥蜴 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距 ...

  7. BZOJ1066 SCOI2007 蜥蜴 【网络流-最大流】

    BZOJ1066 SCOI2007 蜥蜴 Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离 ...

  8. bzoj1066: [SCOI2007]蜥蜴(最大流)

    1066: [SCOI2007]蜥蜴 题目:传送门 题解: 哇QTT大佬一眼秒算法...ORT 其实很容易就可以看出来是一道最大流 因为有边的使用限制,那么就可以直接当成是流量来处理嘛 因为是对点进行 ...

  9. P2472 [SCOI2007]蜥蜴(最大流)

    P2472 [SCOI2007]蜥蜴 自己第一道独立做题且一遍AC的网络流题纪念... 看到这道题我就想到网络流建图的方式了... 首先根据每个高度,我们将每个点拆成两个点限流.之后根据跳的最大距离, ...

随机推荐

  1. 关于mysql连接时候出现"error 2003: can't connect to mysql server on 'localhost'(10061)问题的解决

    天,在使用navicat Premium 连接数据库时,出现了一个弹出窗口显示: "error 2003: can't connect to mysql server on 'localho ...

  2. 一些matlab教程资源收藏,使用matlab编程的人还是挺多的

    Matlab教程专题资源免费下载整理合集收藏 <MATLAB从入门到精通>高清文字版[PDF] 103.9MB 简体中文 <矩阵实验室>(Mathworks.Matlab.R2 ...

  3. 016---Django的ModelForm

    对于forms组件虽然可以帮我们渲染html页面,也可以做校验,但是,保存到数据库要取各字段的值,还要手动保存.所以引入了一个新的组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把 ...

  4. javascript 自定义发布与订阅

    //声明一个类,与普通的类的声明不一样, function Girl() { //将类的事件声明成一个私有的属性,里面是一个对象 this._events = {} } /* { "失恋&q ...

  5. Messy Code in Windows Server 2008 R2 English Edition

          We always use Windows Server 2008 R2 English operation system. And it doesn't have any problem ...

  6. Qt Qwdget 汽车仪表知识点拆解3 进度条编写

    先贴上效果图,注意,没有写逻辑,都是乱动的 这篇我来说说左侧的这个进度条的实现原理,其实更简单,哈哈哈 有一个大的widget,根据素材,我放了10个label 剩下的就是写一个函数,根据数据的不同, ...

  7. SetWindowPos,RegisterHotKey,GlobalAddAtom的用法

    还以为SetWindowPos是给Frm的子框架间编写的,原来是给mainfrm写的,可以把你写的主窗口置顶,置底(看样子应该可以变成桌面了,还没试呢,才忙到现在...) 子窗口的遮挡可以使用窗口的样 ...

  8. zabbix 语音告警

    之前的文章中已经实现了zabbix 邮件告警和微信告警,生产环境上测试出消息抵达很及时,但是!万一服务器在大半夜突发故障微信.邮件这些通知都是废物了,大晚上还能听到微信通知吗?显然不可能(我的某朋友就 ...

  9. 九度OJ--1167(C++)

    #include <iostream>#include <algorithm>#include <map> using namespace std; int mai ...

  10. 详细解析@Resource和@Autowired的区别 , 以及@Qualifier的作用

    (41)  (0) 首先 . @Resource是javax.annotation 包中的注解类 , 是jdk中封装的 . @AutoWired是spring的中注解,依赖于spring上下文. 相同 ...