BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )
2015-12-11 13:14
381 查看
结点容量..拆点然后随便写
---------------------------------------------------------------
#include<cstdio>#include<cstring>#include<algorithm> using namespace std; #define chk(x, y) (x >= 0 && x < R && y >= 0 && y < C) const int maxn = 10000;const int maxm = 2900; int h[maxn], cnt[maxn];int X[maxm][maxm], Y[maxm][maxm];int R, C, D, V, S, T, N;char s[maxm]; struct edge { int to, cap; edge *next, *rev;} E[1000000], *pt = E, *head[maxn], *p[maxn], *cur[maxn]; inline void Add(int u, int v, int w) { pt->to = v; pt->cap = w; pt->next = head[u]; head[u] = pt++;} inline void AddEdge(int u, int v, int w) { Add(u, v, w); Add(v, u, 0); head[u]->rev = head[v]; head[v]->rev = head[u];} void Init() { V = N = 0; scanf("%d%d%d", &R, &C, &D); memset(X, -1, sizeof X); for(int i = 0; i < R; i++) { scanf("%s", s); for(int j = 0; j < C; j++) if(s[j] > '0') { X[i][j] = V++; Y[i][j] = V++; AddEdge(X[i][j], Y[i][j], s[j] - '0'); } } S = V++; T = V++; for(int i = 0; i < R; i++) for(int j = 0; j < C; j++) if(~X[i][j]) for(int d = 1; d <= D; d++) for(int k = 0; k <= d; k++) { int x = i + k, y = j + d - k; if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn); x = i - k, y = j - d + k; if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn); x = i + k, y = j - d + k; if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn); x = i - k, y = j + d - k; if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn); } for(int i = 0; i < R; i++) { scanf("%s", s); for(int j = 0; j < C; j++) { if(~X[i][j] && (i < D || j < D || i + D >= R || j + D >= C)) AddEdge(Y[i][j], T, maxn); if(s[j] != '.') AddEdge(S, X[i][j], 1), N++; } } } void Solve() { memset(cnt, 0, sizeof cnt); memset(h, 0, sizeof h); cnt[0] = V; for(int i = 0; i < V; i++) cur[i] = head[i]; int Flow = 0; edge* e; for(int x = S, A = maxn; h[S] < V; ) { for(e = cur[x]; e; e = e->next) if(h[e->to] + 1 == h[x] && e->cap) break; if(e) { p[e->to] = cur[x] = e; A = min(A, e->cap); if((x = e->to) == T) { for(; x != S; x = p[x]->rev->to) { p[x]->cap -= A; p[x]->rev->cap += A; } Flow += A; A = maxn; } } else { if(!--cnt[h[x]]) break; h[x] = V; for(e = head[x]; e; e = e->next) if(h[e->to] + 1 < h[x] && e->cap) { h[x] = h[e->to] + 1; cur[x] = e; } cnt[h[x]]++; if(x != S) x = p[x]->rev->to; } } printf("%d\n", N - Flow); } int main() { Init(); Solve(); return 0;}---------------------------------------------------------------
1066: [SCOI2007]蜥蜴
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2516 Solved: 1240
[Submit][Status][Discuss]
Description
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。Input
输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。Output
输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。Sample Input
5 8 200000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
Sample Output
1HINT
100%的数据满足:1<=r, c<=20, 1<=d<=4Source
Pku 2711 Leapin' Lizards相关文章推荐
- 同步网络请求 类封装,包括get请求和post请求,可选择是否进行JSON解析
- npm install —— 从一个简单例子,看本地安装与全局安装的区别
- Mac 应用开发--Cocoa运用程序显示或隐藏MainNemu
- ThinkPHP
- ReactNative 开发入门教程
- GitHub实战系列~4.把github里面的库克隆到指定目录+日常使用 2015-12-11
- C#利用反射动态绑定事件
- Servelt学习笔记之二——使用Servlet提取表单中的数据
- Struts2学习笔记(一)
- 收集表的统计信息时并发过高
- 随机抛硬币
- Unity 5.x BuildAssetBundles 角色换装 基础使用
- jsp表单的客户端验证
- APUE学习之----进程通信fifo实现管道
- CSS检测的高像素密度屏幕设备
- 平常心
- 关于浏览器内核的认知
- java中对集合对象list的几种循环访问
- JAVA 十进制转十六进制(蓝桥杯
- 【转】App开发者必备的运营、原型、UI设计工具整理