[BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】
题目链接:BZOJ - 1066
题目分析
题目限制了高度为 x 的石柱最多可以有 x 只蜥蜴从上面跳起,那么就可以用网络流中的边的容量来限制。我们把每个石柱看作一个点,每个点拆成 i1, i2,从 i1 到 i2 连一条边,容量为这个石柱 i 的高度,即跳跃次数限制。来到这个石柱就是向 i1 连边,从这个石柱跳起就是从 i2 向外连边,这样只要从石柱 i 跳起就一定会消耗 i1 到 i2 的边的容量。如果 i 有蜥蜴,就从 S 到 i1 连一条容量为 1 的边,如果从石柱 i 能跳出边界,就从 i2 到 T 连 INF 的边。如果从石柱 i 能跳到石柱 j ,就从 i2 到 j1 连 INF 的边。这样求出的最大流就是能够跳出的蜥蜴的数量。
题目还限制了“任何时刻不能有两只蜥蜴在同一个石柱上”,但是想一想就会发现,这个限制其实并没有影响,只要我们按照合适的顺序让蜥蜴们先后跳跃,就一样可以让那些应该跳出的蜥蜴跳出。
另外,题目要求输出不能跳出的蜥蜴的数量,结果我直接输出了能跳出的数量...于是对着数据调了1h...最后发现是输出的东西不对...QAQ
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int MaxR = 20 + 5, MaxN = 400 * 2 + 5, MaxM = 500000 * 2 + 5, INF = 0x3fffffff;
int n, m, Dis, Top, S, T, Tot, Ans, Sum;
int Num[MaxN], d[MaxN];
bool Be[MaxR][MaxR];
char Str[MaxR];
struct Edge
{
int v, w;
Edge *Next, *Other;
} E[MaxM], *P = E, *Point[MaxN], *Last[MaxN];
inline void AddEdge(int x, int y, int z) {
Edge *Q = ++P; ++P;
P -> v = y; P -> w = z;
P -> Next = Point[x]; Point[x] = P; P -> Other = Q;
Q -> v = x; Q -> w = 0;
Q -> Next = Point[y]; Point[y] = Q; Q -> Other = P;
}
struct ES
{
int x, y, z;
ES() {}
ES(int a, int b, int c) {
x = a; y = b; z = c;
}
} JF[MaxN];
typedef double DB;
bool Check(int x, int y) {
if ((x - 1) < Dis || (y - 1) < Dis) return true;
if ((n - x) < Dis || (m - y) < Dis) return true;
return false;
}
inline DB Sqr(DB x) {return x * x;}
DB Calc(DB x, DB y, DB xx, DB yy) {
return sqrt(Sqr(x - xx) + Sqr(y - yy));
}
inline int gmin(int a, int b) {return a < b ? a : b;}
int DFS(int Now, int Flow) {
if (Now == T) return Flow;
int ret = 0;
for (Edge *j = Last[Now]; j; j = j -> Next) {
if (j -> w && d[Now] == d[j -> v] + 1) {
Last[Now] = j;
int p = DFS(j -> v, gmin(j -> w, Flow - ret));
j -> w -= p; j -> Other -> w += p; ret += p;
if (ret == Flow) return ret;
}
}
if (d[S] >= Tot) return ret;
if (--Num[d[Now]] == 0) d[S] = Tot;
++Num[++d[Now]];
Last[Now] = Point[Now];
return ret;
}
int main()
{
scanf("%d%d%d", &n, &m, &Dis);
Top = 0;
for (int i = 1; i <= n; ++i) {
scanf("%s", Str);
for (int j = 1; j <= m; ++j) {
if (Str[j - 1] != '0') {
JF[++Top] = ES(i, j, Str[j - 1] - '0');
}
}
}
Sum = 0;
for (int i = 1; i <= n; ++i) {
scanf("%s", Str);
for (int j = 1; j <= m; ++j) {
if (Str[j - 1] == 'L') {
Be[i][j] = true;
++Sum;
}
else Be[i][j] = false;
}
}
S = Top * 2 + 1; T = S + 1; Tot = T;
for (int i = 1; i <= Top; ++i) {
int xx = JF[i].x, yy = JF[i].y;
AddEdge(i, Top + i, JF[i].z);
if (Check(xx, yy)) AddEdge(Top + i, T, INF);
if (Be[xx][yy]) AddEdge(S, i, 1);
for (int j = 1; j <= Top; ++j) {
if (j == i) continue;
if (Calc(xx, yy, JF[j].x, JF[j].y) <= (DB)Dis)
AddEdge(Top + i, j, INF);
}
}
for (int i = 1; i <= Tot; ++i) Last[i] = Point[i];
memset(Num, 0, sizeof(Num)); Num[0] = Tot;
memset(d, 0, sizeof(d));
Ans = 0;
while (d[S] < Tot) Ans += DFS(S, INF);
printf("%d\n", Sum - Ans);
return 0;
}
[BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】的更多相关文章
- 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 ...
- POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)
POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...
- BZOJ 1066 [SCOI2007]蜥蜴(最大流)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1066 [题目大意] 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些 ...
- bzoj 1066: [SCOI2007] 蜥蜴
这道题还是挺好想的,但我一开始还是想错了…… 把每个石柱拆成两个点,一个入度,一个出度,两个点连一条容量为高度的边,这样就可以限制从此石柱上经过的蜥蜴的数量.关于蜥蜴是否单独成点,我是单独当成了一个点 ...
- bzoj 1066 : [SCOI2007]蜥蜴 网络流
题目链接 给一个n*m的图, 里面每一个点代表一个石柱, 石柱有一个高度. 初始时有些石柱上面有蜥蜴, 蜥蜴可以跳到距离他曼哈顿距离小于等于d的任意一个石柱上,跳完后, 他原来所在的石柱高度会减一, ...
- 1066: [SCOI2007]蜥蜴
1066: [SCOI2007]蜥蜴 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3545 Solved: 1771[Submit][Status] ...
- [SCOI2007] 蜥蜴 (最大流)
[SCOI2007] 蜥蜴 题目背景 07四川省选 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1 ...
- P2472 [SCOI2007]蜥蜴 (最大流)
题目 P2472 [SCOI2007]蜥蜴 解析 这个题思路比较清晰,本(qi)来(shi)以(jiu)为(shi)无脑建图跑最大流,结果挂了,整了一个小时后重新建图才过的. 建立一个超级源点和一个超 ...
随机推荐
- 编译LOADCEPC.EXE程序
1.安装编译工具 安装MSVC152路径C:/MSVC; 安装MASM611可以自己指定E:/MASM611; 命令行编译 相关文件配置 修改setupen2.bat 如下: :PATH_DONE s ...
- java输入输出
1. import java.io.*;//写进文档,然后又在显示器显示出来.public class fileinputstream{public static void main(String[] ...
- 高效 css 整理
避免通用规则 请确保规则不以通用类型作为结束! 不要用标签名或 classes 来限制 ID 规则 如果规则的关键选择器为 ID 选择器,则没有必要为规则增加标签名.因为 ID 是唯一的,增加标签只会 ...
- 关于javascript dom扩展:Selector API
众多javascript库中最常用的一项功能,就是根据css选择符选择与某个模式匹配的DOM元素.之前由于对javascript的认识较低,对javascript对DOM操作还停留在getElemen ...
- Oracle修改被占用的临时表结构
这两天在修改临时表的类型时,提示”attempt to create,alter or drop an index on temporary table already in use“的错误,由于临时 ...
- 给Sublime Text2安装轻量级代码提示插件:SublimeCodeIntel
步骤: 1.下载SublimeCodeIntel(地址https://github.com/SublimeCodeIntel/SublimeCodeIntel): 2.将下载的压缩包解压,并放置在Pa ...
- sql server查询时候注意的基本优化常识
1.在Where条件中尽量不要在=号左边进行函数.运算符.或表达式计算 2.在Where中尽量避免出现!=或<>操作符: 3.在Where中尽量避免对字段进行null值判定: 4.使用Li ...
- cookie防篡改
概述: 除了 session 外,一般不会在客户端的 cookies 里保存过于重要的凭据,但电商应用有时候不可避免地存储了一些敏感数据到客户端,当然不希望被篡改. 目的: 让服务器端能识别cooki ...
- A除以B_2
本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成立. 输入格式: 输入在1行中依次给出A和B,中间以1空格分隔. 输出格 ...
- oracle 触发器number判断空值,:NEW赋值,for each row,sql变量引号,to_date,to_char
1.number类型在库中可能存在null这种数据 判断是否为空时要用如下: IF(nvl(:NEW.BACAH,0) <>0) 不能用IF(BACAH IS NOT NULL) 2. 2 ...