bzoj1066[SCOI2007]蜥蜴

bzoj1066[SCOI2007]蜥蜴

题意:

r行c列网格图上有一些高低不平的柱子,一些柱子上有蜥蜴,一只蜥蜴一次能跳距离为d,每次蜥蜴跳跃时出发柱子高度减一,当柱子高度为0时消失,问最少多少蜥蜴不能跳出网格图。r,c≤20,d≤4

题解:

裸最大流,每个柱子拆成X,Y两点,两点之间连柱子的高度,所有Yi向可达柱子的Xi连边,s向所有蜥蜴初始位置连边,所有可以跳出图的柱子向t连边。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define maxn 1000
 6 #define inc(i,j,k) for(int i=j;i<=k;i++)
 7 #define INF 0x3fffffff
 8 using namespace std;
 9
10 struct e{int t,c,n;}; e es[maxn*40]; int g[maxn],ess;
11 inline void pe(int f,int t,int c){
12     es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,0,g[t]}; g[t]=ess;
13 }
14 inline void init(){
15     ess=-1; memset(g,-1,sizeof(g));
16 }
17 queue <int> q; int h[maxn];
18 bool bfs(int s,int t){
19     memset(h,-1,sizeof(h)); while(!q.empty())q.pop(); h[s]=0; q.push(s);
20     while(! q.empty()){
21         int x=q.front(); q.pop();
22         for(int i=g[x];i!=-1;i=es[i].n)if(es[i].c&&h[es[i].t]==-1)h[es[i].t]=h[x]+1,q.push(es[i].t);
23     }
24     return h[t]!=-1;
25 }
26 int dfs(int x,int t,int f){
27     if(x==t)return f; int u=0;
28     for(int i=g[x];i!=-1;i=es[i].n)if(es[i].c&&h[es[i].t]==h[x]+1){
29         int w=dfs(es[i].t,t,min(f,es[i].c)); f-=w; u+=w; es[i].c-=w; es[i^1].c+=w; if(f==0)return u;
30     }
31     if(u==0)h[x]=-1; return u;
32 }
33 int dinic(int s,int t){
34     int f=0; while(bfs(s,t))f+=dfs(s,t,INF); return f;
35 }
36 inline int dis(int x1,int y1,int x2,int y2){
37     return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
38 }
39 int r,c,d,s,t,pos[30][30],x[500],y[500],he[500],n,tot; char str[30];
40 int main(){
41     scanf("%d%d%d",&r,&c,&d); n=tot=0;
42     inc(i,1,r){
43         scanf("%s",str);
44         inc(j,0,c-1)if(str[j]!=‘0‘)
45             n++,x[n]=i,y[n]=j+1,he[n]=str[j]-‘0‘,pos[i][j+1]=n;
46     }
47     init(); s=0; t=2*n+1;
48     inc(i,1,r){
49         scanf("%s",str);
50         inc(j,0,c-1)if(str[j]==‘L‘)pe(s,pos[i][j+1],1),tot++;
51     }
52     inc(i,1,n){
53         pe(i,n+i,he[i]);
54         inc(j,1,n)if(i!=j&&dis(x[i],y[i],x[j],y[j])<=d*d)pe(n+i,j,INF);
55         if(x[i]<=d||r+1-x[i]<=d||y[i]<=d||c+1-y[i]<=d)pe(n+i,t,INF);
56     }
57     printf("%d",tot-dinic(s,t)); return 0;
58 }

20160608

时间: 2024-11-14 01:39:44

bzoj1066[SCOI2007]蜥蜴的相关文章

[BZOJ1066] [SCOI2007] 蜥蜴 (网络流)

Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上.石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失.以后其他蜥蜴不能落脚.任何时刻不能有两只蜥蜴在同一个石柱上. Input 输入第一行为三个整数r,c,d,即地图的规模与最大跳

【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流

[bzoj1066]: [SCOI2007]蜥蜴 把石柱拆点,流量为高度 然后S与蜥蜴连流量1的边 互相能跳到的石柱连inf的边 石柱能到边界外的和T连inf的边 然后跑dinic就好了 1 /* http://www.cnblogs.com/karl07/ */ 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <al

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

[bzoj1066][SCOI2007]蜥蜴 Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上.石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失.以后其他蜥蜴不能落脚.任何时刻不能有两只蜥蜴在同一个石柱上. Input 输入第

[BZOJ1066][luogu_P2472][SCOI2007]蜥蜴

[BZOJ1066][luogu_P2472][SCOI2007]蜥蜴 试题描述 在一个 \(r\) 行 \(c\) 列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为 \(1\),蜥蜴的跳跃距离是 \(d\),即蜥蜴可以跳到平面距离不超过 \(d\) 的任何一个石柱上.石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减 \(1\)(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为 \(1\),则蜥蜴离开

SCOI2007蜥蜴

Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱 上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上.石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高 度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失.以后其他蜥蜴不能落脚.任何时刻不能有两只蜥蜴在同 一个石柱上. Input 输入第一行为三个整数r,c,d,即地图的规模与

[SCOI2007] 蜥蜴 (最大流)

[SCOI2007] 蜥蜴 题目背景 07四川省选 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上.石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失.以后其他蜥蜴不能落脚.任何时刻不能有两只蜥蜴在同一个石柱上. 输入输出格式 输入格式:

P2472 [SCOI2007]蜥蜴(网络流)

P2472 [SCOI2007]蜥蜴 把每个点拆成2个点,两点之间连边的边权为石柱高度 新建虚拟源点$S$和汇点$T$ $S$向所有有蜥蜴的点连边,边权1 其他边都连$inf$ 剩下就是裸的$dinic$辣 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 200005 inline int Min(int

题解 P2472 【[SCOI2007]蜥蜴】

题目链接 Solution [SCOI2007]蜥蜴 题目大意:给定一个\(n\)行\(m\)列的地图,每个点有一个经过次数限制,可以从一个点跳到与它距离不超过\(d\)的另一个点.问有多少只蜥蜴不能从地图中出去 题目分析:有多少只蜥蜴不能从地图中出去,可以转化成最多有多少只蜥蜴可以从地图中出去.然后从一个点跳到另一个点我们自然而然想到连有向边,每个点的经过次数限制可以看做是流量上限.最多有多少只蜥蜴可以出去,就是求最大流量.这不就是一个最大流么.然后我们来看核心--建图 首先,普通的最大流问题

[BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】

题目链接:BZOJ - 1066 题目分析 题目限制了高度为 x 的石柱最多可以有 x 只蜥蜴从上面跳起,那么就可以用网络流中的边的容量来限制.我们把每个石柱看作一个点,每个点拆成 i1, i2,从 i1 到 i2 连一条边,容量为这个石柱 i 的高度,即跳跃次数限制.来到这个石柱就是向 i1 连边,从这个石柱跳起就是从 i2 向外连边,这样只要从石柱 i 跳起就一定会消耗 i1 到 i2 的边的容量.如果 i 有蜥蜴,就从 S 到 i1 连一条容量为 1 的边,如果从石柱 i 能跳出边界,就从