HDU 2732 Leapin' Lizards(最大流)

Leapin‘ Lizards


Problem Description

Your platoon of wandering lizards has entered a strange room in the labyrinth you are exploring. As you are looking around for hidden treasures, one of the rookies steps on an innocent-looking stone and the room‘s floor suddenly disappears! Each lizard in your platoon is left standing on a fragile-looking pillar, and a fire begins to rage below... Leave no lizard behind! Get as many lizards as possible out of the room, and report the number of casualties.
The pillars in the room are aligned as a grid, with each pillar one unit away from the pillars to its east, west, north and south. Pillars at the edge of the grid are one unit away from the edge of the room (safety). Not all pillars necessarily have a lizard. A lizard is able to leap onto any unoccupied pillar that is within d units of his current one. A lizard standing on a pillar within leaping distance of the edge of the room may always leap to safety... but there‘s a catch: each pillar becomes weakened after each jump, and will soon collapse and no longer be usable by other lizards. Leaping onto a pillar does not cause it to weaken or collapse; only leaping off of it causes it to weaken and eventually collapse. Only one lizard may be on a pillar at any given time.

Input

The input file will begin with a line containing a single integer representing the number of test cases, which is at most 25. Each test case will begin with a line containing a single positive integer n representing the number of rows in the map, followed by a single non-negative integer d representing the maximum leaping distance for the lizards. Two maps will follow, each as a map of characters with one row per line. The first map will contain a digit (0-3) in each position representing the number of jumps the pillar in that position will sustain before collapsing (0 means there is no pillar there). The second map will follow, with an ‘L‘ for every position where a lizard is on the pillar and a ‘.‘ for every empty pillar. There will never be a lizard on a position where there is no pillar.Each input map is guaranteed to be a rectangle of size n x m, where 1 ≤ n ≤ 20 and 1 ≤ m ≤ 20. The leaping distance is
always 1 ≤ d ≤ 3.

Output

For each input case, print a single line containing the number of lizards that could not escape. The format should follow the samples provided below.

Sample Input

4

3 1

1111

1111

1111

LLLL

LLLL

LLLL

3 2

00000

01110

00000

.....

.LLL.

.....

3 1

00000

01110

00000

.....

.LLL.

.....

5 2

00000000

02000000

00321100

02000000

00000000

........

........

..LLLL..

........

........

Sample Output

Case #1: 2 lizards were left behind.

Case #2: no lizard was left behind.

Case #3: 3 lizards were left behind.

Case #4: 1 lizard was left behind.

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<string>
  4 #include<cstring>
  5 #include<queue>
  6 #include<vector>
  7 #include<algorithm>
  8 using namespace std;
  9
 10 struct Edge
 11 {
 12     int from,to,cap,flow;
 13 };
 14 const int maxn=1005;
 15 const int inf=0x3f3f3f;
 16
 17 struct dinic
 18 {
 19     int n,m,s,t;
 20     vector<Edge>edges;
 21     vector<int>G[maxn];
 22     bool vis[maxn];
 23     int d[maxn];
 24     int cur[maxn];
 25
 26     void init(int num)
 27     {
 28         for(int i=0;i<num;i++)G[i].clear();
 29         edges.clear();
 30     }
 31
 32     void addedge(int from,int to,int cap)
 33     {
 34         edges.push_back((Edge){from,to,cap,0});
 35         edges.push_back((Edge){to,from,0,0});
 36         int m=edges.size();
 37         G[from].push_back(m-2);
 38         G[to].push_back(m-1);
 39     }
 40
 41     bool bfs()
 42     {
 43         memset(vis,0,sizeof(vis));
 44         queue<int>q;
 45         q.push(s);
 46         d[s]=0;
 47         vis[s]=1;
 48         while(!q.empty())
 49         {
 50             int x=q.front();q.pop();
 51             for(int i=0;i<G[x].size();i++)
 52             {
 53                 Edge& e=edges[G[x][i]];
 54                 if(!vis[e.to]&&e.cap>e.flow)
 55                 {
 56                     vis[e.to]=1;
 57                     d[e.to]=d[x]+1;
 58                     q.push(e.to);
 59                 }
 60             }
 61         }
 62         return vis[t];
 63     }
 64
 65     int dfs(int x,int a)
 66     {
 67         if(x==t||a==0)return a;
 68         int flow=0,f;
 69         for(int& i=cur[x];i<G[x].size();i++)
 70         {
 71             Edge& e=edges[G[x][i]];
 72             if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
 73             {
 74                 e.flow+=f;
 75                 edges[G[x][i]^1].flow-=f;
 76                 flow+=f;
 77                 a-=f;
 78                 if(a==0)break;
 79             }
 80         }
 81         return flow;
 82     }
 83
 84     int maxflow(int s,int t)
 85     {
 86         this->s=s,this->t=t;
 87         int flow=0;
 88         while(bfs())
 89         {
 90             memset(cur,0,sizeof(cur));
 91             flow+=dfs(s,inf);
 92         }
 93         return flow;
 94     }
 95 }dc;
 96
 97 int main()
 98 {
 99     int T;
100     scanf("%d",&T);
101     for(int kase=1;kase<=T;kase++)
102     {
103         int m,n,d,sum=0;
104         scanf("%d%d",&n,&d);
105         for(int i=0;i<n;i++)
106         {
107             string s;
108             cin>>s;
109             if(i==0)m=s.size(),dc.init(2*n*m+2);
110             for(int j=0;j<m;j++)
111             {
112                 int id=i*m+j+1;
113                 if(s[j]-‘0‘>0)
114                 {
115                     dc.addedge(id,id+m*n,s[j]-‘0‘);
116                     if(i<d||i+d>=n||j<d||j+d>=m)
117                         dc.addedge(id+n*m,2*n*m+1,inf);
118                     else
119                     {
120                         for(int k=0;k<n;k++)
121                             for(int l=0;l<m;l++)
122                             {
123                                 int id2=k*m+l+1;
124                                 if(id==id2)continue;
125                                 if(abs(i-k)+abs(j-l)<=d)
126                                     dc.addedge(id+n*m,id2,inf);
127                             }
128                     }
129                 }
130             }
131         }
132         for(int i=0;i<n;i++)
133         {
134             string s;
135             cin>>s;
136             for(int j=0;j<s.size();j++)
137                 if(s[j]==‘L‘)
138                 {
139                     sum++;
140                     dc.addedge(0,i*m+j+1,1);
141                 }
142         }
143         int ans=sum-dc.maxflow(0,2*m*n+1);
144         if(ans==0) printf("Case #%d: no lizard was left behind.\n",kase);
145         else if(ans==1) printf("Case #%d: 1 lizard was left behind.\n",kase);
146         else printf("Case #%d: %d lizards were left behind.\n",kase,ans);
147     }
148     return 0;
149 }

HDU 2732 Leapin' Lizards(最大流)

时间: 2024-10-19 08:15:55

HDU 2732 Leapin' Lizards(最大流)的相关文章

hdu 2732 Leapin&#39; Lizards(最大流)Mid-Central USA 2005

废话: 这道题不难,稍微构造一下图就可以套最大流的模板了.但是我还是花了好久才解决.一方面是最近确实非常没状态(托词,其实就是最近特别颓废,整天玩游戏看小说,没法静下心来学习),另一方面是不够细心,输出格式错了大意没有发现死一只和死多只之间的区别,卡在那里动不了. 题意: 在一张n*m的地图中,有一群蜥蜴,这群蜥蜴每次可以跳跃曼哈顿距离d(曼哈顿距离——dis(a, b) = |ax-bx|+|ay-by|,之后所有的距离都是曼哈顿距离),这些蜥蜴只能在地图上的一些柱子上跳跃.柱子i最多可以支持

HDU 2732 Leapin&#39; Lizards(拆点+最大流)

题目意思是有一些蜥蜴在一个迷宫里面,求这些蜥蜴还有多少是无论如何都逃不出来的.题目只给定一个行数n,一个最远能够跳跃的距离d.每只蜥蜴有一个初始的位置,题目保证这些位置都有一些柱子,但是它每离开一根柱子,柱子的高度就会降低1m,问最多能有多少只跳不出去. 将每个柱子在的点进行拆点,把每一个点拆完之后连一条容量为所在点柱子高度的边.从原点连一条容量为1的边,然后找到每个可以直接跳出的点,将这些点与汇点 相连容量为无穷.每个柱子与它可以到达的点的容量也为无穷. Leapin' Lizards Tim

HDU 2732 Leapin&#39; Lizards(拆点+最大流)

HDU 2732 Leapin' Lizards 题目链接 题意:有一些蜥蜴在一个迷宫里面,有一个跳跃力表示能跳到多远的柱子,然后每根柱子最多被跳一定次数,求这些蜥蜴还有多少是无论如何都逃不出来的. 思路:把柱子拆点建图跑最大流即可,还是挺明显的 代码: #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <algorithm> using

HDU 2732 Leapin&#39; Lizards(拆点法+最大流)

该题是一道比较简单拆点+最大流的题目,因为每个柱子都有一定的寿命,很容易将其对应成流量,那么处理结点容量的一般方法当然是拆点法 .该题反而对边的容量没有要求,为保险起见可以设成无穷大.   该题的思路很好想,建议独立编写代码 . 推荐题目: 点击打开链接    结点法的一些见解 也可以看这里. 细节参见代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; const int INF = 100000000;

HDU - 2732 Leapin&#39; Lizards(ISAP Dinic EK)

题目大意:给出两张地图,第一章地图代表的是每根柱子的高度,第二张地图代表的是每只蜥蜴所在的位置 每根柱子只能站一只蜥蜴,蜥蜴离开该柱子时,柱子的高度会下降一个单元,当柱子的高度为0时,该柱子将不可用 现在给出每只蜥蜴能跳跃的距离,问最少有多少只蜥蜴逃不出来 解题思路:将柱子拆成2个点,权值为柱子的高度 将每只蜥蜴所在的位置和超级源点连接,权值为1 将能通到外界的柱子连接到超级汇点,权值为INF 如果柱子间的距离满足蜥蜴跳跃的距离,连接起来,权值为INF 这样图就完成了 ISAP: #includ

HDU 2732 —— Leapin&#39; Lizards

原题:http://acm.hdu.edu.cn/showproblem.php?pid=2732 #include<cstdio> #include<cstring> #include<string> #include<queue> #include<vector> #include<algorithm> #define inf 1e9 using namespace std; const int maxn = 850; const

HDU 2732 Leapin&amp;#39; Lizards(拆点+最大流)

HDU 2732 Leapin' Lizards 题目链接 题意:有一些蜥蜴在一个迷宫里面,有一个跳跃力表示能跳到多远的柱子,然后每根柱子最多被跳一定次数,求这些蜥蜴还有多少是不管怎样都逃不出来的. 思路:把柱子拆点建图跑最大流就可以,还是挺明显的 代码: #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <algorithm> usin

【HDU】 2732 Leapin&#39; Lizards

Leapin' Lizards 题目链接 Leapin'Lizards 题目大意 给你两个图,一个用0,1,2,3表示,一个用 L 或 . 表示.其中用L表示的图中,有L的位置表示有蜥蜴,没有L的位置表示没有蜥蜴.用数字表示的图中,数字表示当前位置柱子的高度,每次一个蜥蜴可以从一个柱子跳到距离d以内的另外一个柱子,每跳跃一次,当前柱子的高度就减一,问最后会有多少只蜥蜴被困在里面. 题解 首先,可以明显的看到,一个柱子是有固定的通过次数的,这一点跟网络流中边的属性很像,但是这里的柱子是点,并不是边

【HDOJ】2732 Leapin&#39; Lizards

贪心+网络流.对于每个结点,构建入点和出点.对于每一个lizard>0,构建边s->in position of lizard, 容量为1.对于pillar>0, 构建边in position of pillar -> out position of pillar, 容量为number of pillar.若沿四个方向移动距离d可以超过边界,则构建边out position of pillar -> t, 容量为INF:否则, 对于曼哈顿距离l(l>0 and l<