【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 <algorithm>
  7 #include <queue>
  8 using namespace std;
  9 const int N=1000000;
 10 const int inf=1e9;
 11 struct edge{
 12     int next,to,c;
 13 }e[N+1];
 14 int ade=1,S=1,T=2,n,m,c,d,CNT=2;
 15 int first[N+1],dis[N+1],now[N+1],mp[25][25],I[25][25],O[25][25];
 16 queue <int> Q;
 17
 18 void addedge(int x,int y,int cap){
 19     e[++ade].next=first[x];
 20     e[ade].to=y;
 21     e[ade].c=cap;
 22     first[x]=ade;
 23     e[++ade].next=first[y];
 24     e[ade].to=x;
 25     e[ade].c=0;
 26     first[y]=ade;
 27 }
 28
 29 #define s e[x].to
 30 #define cap e[x].c
 31 #define CAP e[x^1].c
 32 bool bfs(){
 33     for (int i=1;i<=CNT;i++) dis[i]=inf;
 34     Q.push(S);
 35     dis[S]=0;
 36     while (!Q.empty()){
 37         int p=Q.front();
 38         Q.pop();
 39         for (int x=first[p];x;x=e[x].next){
 40             if (dis[s]>dis[p]+1 && cap>0){
 41                 Q.push(s);
 42                 dis[s]=dis[p]+1;
 43             }
 44         }
 45     }
 46     return dis[T]!=inf;
 47 }
 48
 49 int dfs(int p,int mf){
 50     if (p==T) return mf;
 51     for (int x=now[p];x;x=e[x].next){
 52         now[p]=x;
 53         if (dis[s]==dis[p]+1 && cap>0){
 54             int f=dfs(s,min(mf,cap));
 55             if (f){
 56                 cap-=f;
 57                 CAP+=f;
 58                 return f;
 59             }
 60         }
 61     }
 62     return 0;
 63 }
 64 #undef s
 65 #undef cap
 66 #undef CAP
 67
 68
 69 int dinic(){
 70     int ans=0,f;
 71     while (bfs()){
 72         for (int i=1;i<=CNT;i++) now[i]=first[i];
 73         while (f=dfs(S,inf)){
 74             ans+=f;
 75         }
 76     }
 77     return ans;
 78 }
 79
 80 void make_p(){
 81     for (int i=1;i<=n;i++){
 82         for (int j=1;j<=m;j++){
 83             if (mp[i][j]){
 84                 addedge(I[i][j],O[i][j],mp[i][j]);
 85                 for (int x=i-d;x<=i+d;x++){
 86                     for (int y=j-d;y<=j+d;y++){
 87                         if (abs(i-x)+abs(j-y)>d) continue;
 88                         if (x<1 || x>n || y<1 || y>m) {addedge(O[i][j],T,inf); continue;}
 89                         if (mp[x][y] && (x!=i || y!=j)){addedge (O[i][j],I[x][y],inf); }
 90                     }
 91                 }
 92             }
 93         }
 94     }
 95 }
 96
 97 int main(){
 98     scanf("%d%d%d",&n,&m,&d);
 99     for (int i=1;i<=n;i++){
100         char s[25];
101         scanf("%s",s+1);
102         for (int j=1;j<=m;j++){
103             mp[i][j]=s[j]-‘0‘;
104             if (mp[i][j]) I[i][j]=++CNT,O[i][j]=++CNT;
105         }
106     }
107     make_p();
108     for (int i=1;i<=n;i++){
109         char s[25];
110         scanf("%s",s+1);
111         for (int j=1;j<=m;j++){
112             if (s[j]==‘L‘){
113                 addedge(S,I[i][j],1);
114                 c++;
115             }
116         }
117     }
118     printf("%d\n",c-dinic());
119     return 0;
120 }

时间: 2024-10-06 05:45:56

【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流的相关文章

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 #

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

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

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

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

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

本题想一想应该懂了的. 我们想啊,,每个点都有限制,每个点都可以跳到另一个有限制的点,每个有蜥蜴的点都可以跳到四周的有限制的点,,哈哈,自然会想到网络流. 其中很自然的可以相到,要表示每个点的容量限制,那么就拆点,一个上,一个下,容量为权值 然后向四周连接也就是某个点的下将距离范围内的某个点的上连接,容量为oo 源向蜥蜴连接,容量为1 可以跑到边界外的点的下向汇连接,容量为oo 跑一次最大流,答案就是蜥蜴总数减去最大流. #include <cstdio> #include <cstri

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

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

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

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

[BZOJ1066][luogu_P2472][SCOI2007]蜥蜴

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

[SCOI2007] 蜥蜴 (最大流)

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

题解 P2472 【[SCOI2007]蜥蜴】

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