bzoj 1066 蜥蜴

网络流。

建图:首先将每根柱子拆成两个点。

每根柱子的入点向出点连一条容量为柱子高度的边。

每根柱子的出点向可以到达的柱子的入点连一条容量为正无穷的边。

源点向每根初始有蜥蜴的柱子的入点连一条容量为一的边。

每根可以跳出地图的柱子的出点向汇点连一条容量为正无穷的边。

跑一遍最大流就是最多能逃出的蜥蜴数。

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int dian=8005;
 9 const int bian=160005;
10 const int INF=0x3f3f3f3f;
11 int h[dian],nxt[bian],ver[bian],val[bian],ch[dian];
12 char mapp[25][25],map[25][25];
13 char lala[25];
14 int n,m,d,tot,ans;
15 int S,T;
16 void add(int aa,int bb,int cc){
17     tot++;ver[tot]=bb;nxt[tot]=h[aa];val[tot]=cc;h[aa]=tot;
18     tot++;ver[tot]=aa;nxt[tot]=h[bb];val[tot]=0;h[bb]=tot;
19 }
20 int bh(int aa,int bb,int cc){
21     return (aa-1)*m+bb+cc*n*m;
22 }
23 bool tell(){
24     memset(ch,-1,sizeof(ch));
25     queue<int>q;
26     q.push(S);
27     ch[S]=0;
28     while(!q.empty()){
29         int t=q.front();
30         q.pop();
31         for(int i=h[t];i;i=nxt[i])
32             if(ch[ver[i]]==-1&&val[i]){
33                 q.push(ver[i]);
34                 ch[ver[i]]=ch[t]+1;
35             }
36     }
37     return ch[T]!=-1;
38 }
39 int zeng(int a,int b){
40     if(a==T)
41         return b;
42     int r=0;
43     for(int i=h[a];i&&b>r;i=nxt[i])
44         if(ch[a]+1==ch[ver[i]]&&val[i]){
45             int t=zeng(ver[i],min(b-r,val[i]));
46             val[i]-=t,r+=t,val[i^1]+=t;
47         }
48     if(!r)
49         ch[a]=-1;
50     return r;
51 }
52 int dinic(){
53     int r=0,t;
54     while(tell())
55         while(t=zeng(S,INF))
56             r+=t;
57     return r;
58 }
59 int main(){
60     tot=1;
61     scanf("%d%d%d",&n,&m,&d);
62     S=2*n*m+1,T=2*n*m+2;
63     for(int i=1;i<=n;i++)
64         scanf("%s",mapp[i]+1);
65     for(int i=1;i<=n;i++)
66         for(int j=1;j<=m;j++)
67             map[i][j]=mapp[i][j]-‘0‘;
68     for(int i=1;i<=n;i++)
69         for(int j=1;j<=m;j++)
70             if(map[i][j]){
71                 add(bh(i,j,0),bh(i,j,1),map[i][j]);
72                 for(int k=i-d;k<=i+d;k++)
73                     for(int l=j-d;l<=j+d;l++)
74                         if(k>=1&&k<=n&&l>=1&&l<=m&&(k!=i||l!=j)&&abs(k-i)*abs(k-i)+abs(l-j)*abs(l-j)<=d*d&&map[k][l])
75                             add(bh(i,j,1),bh(k,l,0),INF);
76             }
77     for(int i=1;i<=n;i++)
78         for(int j=1;j<=m;j++)
79             if(min(min(i,n+1-i),min(j,m+1-j))<=d&&map[i][j])
80                 add(bh(i,j,1),T,INF);
81     for(int i=1;i<=n;i++){
82         scanf("%s",lala+1);
83         for(int j=1;j<=m;j++)
84             if(lala[j]==‘L‘){
85                 ans++;
86                 add(S,bh(i,j,0),1);
87             }
88     }
89     printf("%d",ans-dinic());
90     return 0;
91 }

注意:

数组大小要好好算。

读入均为字符串形式。

距离为欧几里得距离。

时间: 2024-09-29 04:31:18

bzoj 1066 蜥蜴的相关文章

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

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

AC日记——[SCOI2007]蜥蜴 bzoj 1066

1066 思路: 网络流最大流: 拆点,每个点拆成两个,流量为这个点的高度: 注意,文中说的距离是曼哈顿距离(劳资以为开根号wa了不知道多少次): 每两个距离不大于d的点连边,流量inf: 如果距离能够延伸到边界外,就将这个点连向t: 最后输出,蜥蜴个数减去最大流: 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <alg

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

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1066 [题目大意] 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴, 你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1, 蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上. 石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1 (如果仍然落在地图内部,则到达的石柱高度不变), 如果该石柱原来高度为1,则蜥蜴离开后消失.以后其

【BZOJ 1066】[SCOI2007]蜥蜴

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

蜥蜴(bzoj 1066)

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

bzoj 1066 : [SCOI2007]蜥蜴 网络流

题目链接 给一个n*m的图, 里面每一个点代表一个石柱, 石柱有一个高度. 初始时有些石柱上面有蜥蜴, 蜥蜴可以跳到距离他曼哈顿距离小于等于d的任意一个石柱上,跳完后, 他原来所在的石柱高度会减一, 如果高度变为0, 那么石柱消失, 无法在跳到这个位置上, 跳到的那个石柱高度不会发生改变, 同一时刻一个石柱无法站两个蜥蜴.问有多少蜥蜴无法跳出边界. 很裸的网络流, 如果一个石柱距离边界距离小于d, 那么向汇点连一条权值为inf的边, 如果一个石柱初始有蜥蜴, 那么源点向这个点连一条1的边, 每个

[BZOJ 1066][SCOI2007]蜥蜴(网络流)

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

BZOJ 1066 SCOI 2007 蜥蜴 最大流

题目大意:给出一张图,每一个点有一个寿命,当有这个寿命值个蜥蜴经过后这个点就会消失,一个蜥蜴可以跳到距离不超过d的点上,问最少有多少只蜥蜴无法跳出这张图. 思路:我们将每个点拆点,然后限制流量为这个点的寿命,之后源点向每个蜥蜴连边,互相能够到达的点之间连边,能够跳出这个图的点和汇点连边,跑最大流就是这个图中最多能够跑出去的蜥蜴数量,最后在用总数减去就是最少不能逃出去的数量. CODE: #include <cmath> #include <queue> #include <c

bzoj 1066: [SCOI2007]蜥蜴

1 #include<cstdio> 2 #include<iostream> 3 #define T 1001 4 #define M 10005 5 #define inf 0x7fffffff 6 #include<cstring> 7 using namespace std; 8 int cnt=1,r,c,d,head[M],next[10*M],u[10*M],v[10*M],sum,f[25][25],d1[M],q[M],ans; 9 char ch[5