题目链接

题意

给定一张网格,格子中有些地方有柱子,有些柱子上面有蜥蜴。

每个柱子只能承受有限只蜥蜴从上面经过。每只蜥蜴每次能走到相距曼哈顿距离\(\leq k\)的格子中去。

问有多少只蜥蜴能走出网格。

分析

参考博文

拆点

因为这道题中的容量不是限制在边上,而是限制在点上的,所以可以考虑将一个点拆成两个点,中间再加一条边,边的容量即为原先点上的值。

想法很重要。

建图

  1. 对于起始有蜥蜴的点,从源点\(s\)连一条容量为\(1\)的边到它;

  2. 对于中间点,拆成两点:点\(1\)到点\(2\)的容量为点的承受值;点\(2\)再代表原先的该点向外连向其他点,权值可以赋为大于等于容量的任意值;

  3. 对于可以直接跳出去的点,向汇点\(e\)连一条边,容量为该点的承受值。

跑最大流

Code

#include <bits/stdc++.h>
#define maxn 1010
#define maxp 1010
#define inf 0x3f3f3f3f
#define id1(i,j) (idx(i,j)<<1)
#define id2(i,j) (id1(i,j)|1)
using namespace std;
typedef long long LL;
int dep[maxp], cur[maxp], n, m, tot, k, ne[maxp];
char cnt[maxn][maxn], s[maxn];
inline int idx(int i, int j) { return (i-1)*m+j; }
inline bool check(int i, int j) { return i > 0 && i <= n && j > 0 && j <= m && cnt[i][j]!='0'; }
struct Edge { int to, ne, c; }edge[maxp<<4];
void add(int u, int v, int c) {
edge[tot] = {v, ne[u], c};
ne[u] = tot++;
edge[tot] = {u, ne[v], 0};
ne[v] = tot++;
}
void init() {
tot = 0; memset(ne, -1, sizeof(ne));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (cnt[i][j] == '0') continue;
if (i-k <= 0 || i+k > n || j-k <= 0 || j+k > m) { add(id1(i,j), 1, cnt[i][j]-'0'); continue; }
add(id1(i,j), id2(i,j), cnt[i][j]-'0');
for (int r = i-k; r <= i+k; ++r) {
for (int c = j-k; c <= j+k; ++c) {
if (abs(i-r)+abs(j-c) > k) continue;
if (check(r, c)) add(id2(i, j), id1(r, c), inf);
}
}
}
}
}
int bfs(int src) {
queue<int> q;
while (!q.empty()) q.pop();
memset(dep, 0, sizeof(dep));
dep[src] = 1;
q.push(src);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = ne[u]; ~i; i = edge[i].ne) {
int v = edge[i].to;
if (edge[i].c > 0 && !dep[v]) {
dep[v] = dep[u]+1;
q.push(v);
}
}
}
return dep[1];
}
int dfs(int u, int flow) {
if (u == 1) return flow;
for (int& i = cur[u]; ~i; i = edge[i].ne) {
int v = edge[i].to;
if (edge[i].c > 0 && dep[v]-dep[u]==1) {
int c = dfs(v, min(flow, edge[i].c));
if (c) {
edge[i].c -= c;
edge[i^1].c += c;
return c;
}
}
}
return 0;
}
int kas;
void work() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i) {
scanf("%s", cnt[i]+1);
}
m = strlen(cnt[1]+1);
init(); int all = 0;
for (int i = 1; i <= n; ++i) {
scanf("%s", s+1);
for (int j = 1; j <= m; ++j) {
if (s[j] == 'L') ++all, add(0, id1(i,j), 1);
}
} int pcnt = id2(n, m)+1, ans=0, ret;
while (bfs(0)) {
for (int i = 0; i < pcnt; ++i) cur[i] = ne[i];
while (ret = dfs(0, inf)) ans += ret;
}
ans = all-ans;
printf("Case #%d: ", ++kas);
if (!ans) puts("no lizard was left behind.");
else if (ans==1) puts("1 lizard was left behind.");
else printf("%d lizards were left behind.\n", ans);
}
int main() {
int T;
scanf("%d", &T);
while (T--) work();
return 0;
}

hdu 2732 Leapin' Lizards 最大流 拆点 建图的更多相关文章

  1. hdu 2732 Leapin' Lizards (最大流 拆点建图)

    Problem Description Your platoon of wandering lizards has entered a strange room in the labyrinth yo ...

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

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

  3. HDU - 2732 Leapin' Lizards (拆点最大流)

    题意:有N*M的矩形,每个格点有一个柱子,每根柱子有高度c,允许蜥蜴经过这根柱子c次,开始有一些蜥蜴在某些柱子上,它们要跳出这个矩形,每步最大能跳d个单位,求最少有多少蜥蜴不能跳出这个矩形. 分析:转 ...

  4. HDU 2732 Leapin' Lizards(最大流)

    http://acm.hdu.edu.cn/showproblem.php?pid=2732 题意: 给出n行的网格,还有若干只蜥蜴,每只蜥蜴一开始就在一个格子之中,并且给出蜥蜴每次的最大跳跃长度d. ...

  5. HDU 2732 Leapin' Lizards

    网络最大流+拆点.输出有坑!!! #include<cstdio> #include<cstring> #include<string> #include<c ...

  6. hdu 2732 Leapin' Lizards(最大流)Mid-Central USA 2005

    废话: 这道题不难,稍微构造一下图就可以套最大流的模板了.但是我还是花了好久才解决.一方面是最近确实非常没状态(托词,其实就是最近特别颓废,整天玩游戏看小说,没法静下心来学习),另一方面是不够细心,输 ...

  7. hdu2732 Leapin' Lizards 最大流+拆点

    Your platoon of wandering lizards has entered a strange room in the labyrinth you are exploring. As ...

  8. HDU 2732 Leapin&#39; Lizards(拆点+最大流)

    HDU 2732 Leapin' Lizards 题目链接 题意:有一些蜥蜴在一个迷宫里面,有一个跳跃力表示能跳到多远的柱子,然后每根柱子最多被跳一定次数,求这些蜥蜴还有多少是不管怎样都逃不出来的. ...

  9. HDU-2732-leapin'Lizards(最大流, 拆点)

    链接: https://vjudge.net/problem/HDU-2732 题意: Your platoon of wandering lizards has entered a strange ...

随机推荐

  1. Python周末21天笔记

    模块一: 基础相互据类型之间的相互转换 1. 字符串str 与 列表 list 与字典 dict 以及 元祖tuple的转换 例一: 把字典的key和value的值取出来,按照顺序存入到list中 d ...

  2. python面试题之介绍一下Python中webbrowser的用法

    所属网站分类: 面试经典 > python 作者:外星人入侵 链接: http://www.pythonheidong.com/blog/article/13/ 来源:python黑洞网 www ...

  3. 容斥原理:HDU-4135Co-prime

    容斥原理公式:这里就需要用到容斥原理了,公式就是:n/2+n/3+n/5-n/(2*3)-n/(2*5)-n/(3*5)+n/(2*3*5). 求的是多个重合区间的里面的数字个数. 解题心得: 1.一 ...

  4. n个人排队都不站在原来的位置

    一.题目描述 有n个人首先站成一排,请问,当n个人第二次再重新排列,每个人都不在原来的位置上,问有多少种站法.例如,原来有3个人,ABC,那么第二次每个人都不在原来的位置上有2种站法,BCA和CAB, ...

  5. Patrick and Shopping

    Patrick and Shopping 今天 Patrick 等待着他的朋友 Spongebob 来他家玩.为了迎接 Spongebob,Patrick 需要去他家附近的两家商店  买一些吃的.他家 ...

  6. hibernate实体xml一对多关系映射

    单向一对多关系映射: 一个房间对应多个使用者,也就是Room實例知道User實例的存在,而User實例則沒有意識到Room實例. 用户表: package onlyfun.caterpillar; p ...

  7. CyclicBarrier源码分析

    CyclicBarrier是通过ReentrantLock(独占锁)和Condition来实现的.下面,我们分析CyclicBarrier中3个核心函数: 构造函数, await()作出分析. 1. ...

  8. Diycode开源项目 MainActivity分析

    1.分析MainActivity整体结构 1.1.首先看一下这个界面的整体效果. 1.2.活动源代码如下 /* * Copyright 2017 GcsSloop * * Licensed under ...

  9. 2 Model层 -定义模型

    1  ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射” ...

  10. Android事件分发机制浅析(3)

    本文来自网易云社区 作者:孙有军 我们只看最重要的部分 1: 事件为ACTION_DOWN时,执行了cancelAndClearTouchTargets函数,该函数主要清除上一次点击传递的路径,之后执 ...