HDU2732:Leapin' Lizards(最大流)

Leapin‘ Lizards

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4250    Accepted Submission(s): 1705

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2732

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.

题意:

给出一个n*m的矩阵,输入两次,第一次表示上面的柱子,如果有数值,就代表这根柱子最多只能被几只蜥蜴上来过;第二次如果有L,这代表这个位置有只蜥蜴。

会给出蜥蜴的最大跳跃距离d,当然可以跳多次,只能跳到柱子上。问最多有多少只蜥蜴可以跳出这个矩阵。

题解:

考虑最大流,可以这样建图:

首先将每个柱子拆点,边权为柱子的最大容量。

然后预处理能跳出矩阵的格子(有柱子),让汇点与这些格子的出度点连边,边权为INF;然后遍历这个图,对能互相跳的柱子连边,一个柱子的出度点连续另一个柱子的入读点,边权为INF。

最后让源点与每个蜥蜴连边,权值为1。

最后跑个最大流这题基本就完了~最后要注意下输出...

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#define INF 99999999
#define t 1000
using namespace std;

const int N = 30;
int T,Case,tot,D,n,m;
int head[1005],d[1005],cur[1005];
int map[N][N];

struct Edge{
    int v,next,c;
}e[500000];
void adde(int u,int v,int c){
    e[tot].v=v;e[tot].c=c;e[tot].next=head[u];head[u]=tot++;
    e[tot].v=u;e[tot].c=0;e[tot].next=head[v];head[v]=tot++;
}
int dis(int x1,int y1,int x2,int y2){
    return abs(x1-x2)+abs(y1-y2);
}
bool bfs(int S,int T){
    memset(d,0,sizeof(d));d[S]=1;
    queue <int > q;q.push(S);
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(!d[v] && e[i].c>0){
                d[v]=d[u]+1;
                q.push(v);
            }
        }
    }
    return d[T]!=0;
}
int dfs(int s,int a){
    int flow=0,f;
    if(s==t || a==0) return a;
    for(int &i=cur[s];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(d[v]!=d[s]+1) continue ;
        f=dfs(v,min(a,e[i].c));
        if(f){
            e[i].c-=f;
            e[i^1].c+=f;
            flow+=f;
            a-=f;
            if(a==0) break;
        }
    }
    if(!flow) d[s]=-1;
    return flow;
}
int Dinic(){
    int max_flow=0;
    while(bfs(0,t)){
        for(int i=0;i<=t;i++) cur[i]=head[i];
        max_flow+=dfs(0,INF);
    }
    return max_flow;
}
int main(){
    scanf("%d",&T);
    while(T--){
        Case++;
        tot=0;memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&D);
        char s[N];
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            m = strlen(s);
            for(int j=0;j<m;j++){
                if(s[j]==0) continue ;
                map[i][j+1]=s[j]-‘0‘;
                if(i<=D || n-i+1<=D || j+1<=D || m-j<=D){
                    int u = (i-1)*m+j+1;
                    adde(u+400,t,map[i][j+1]);
                }
            }
        }
        int sum = 0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(map[i][j]) adde((i-1)*m+j,(i-1)*m+j+400,map[i][j]);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(map[i][j]){
                    for(int _i=max(1,i-3);_i<=min(n,i+3);_i++){
                        for(int _j=max(1,j-3);_j<=min(m,j+3);_j++){
                            if(!map[_i][_j] || (i==_i && j==_j)) continue ;
                            if(dis(i,j,_i,_j)<=D)
                                adde((i-1)*m+j+400,(_i-1)*m+_j,INF);
                        }
                    }
                }
            }
        }
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            for(int j=1;j<=m;j++)
            if(s[j-1]==‘L‘) adde(0,(i-1)*m+j,1),sum++;
        }
        int cnt=Dinic();
        int left = sum-cnt;
        if(!left) printf("Case #%d: no lizard was left behind.\n",Case);
        else if(left==1) printf("Case #%d: 1 lizard was left behind.\n",Case);
        else printf("Case #%d: %d lizards were left behind.\n",Case,left);
    }
    return 0;
}

HDU2732:Leapin' Lizards(最大流)

原文地址:https://www.cnblogs.com/heyuhhh/p/10117129.html

时间: 2024-10-29 19:09:50

HDU2732:Leapin' Lizards(最大流)的相关文章

hdu2732 Leapin&#39; Lizards (网络流dinic)

D - Leapin' Lizards Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Your platoon of wandering lizards has entered a strange room in the labyrinth you are exploring. As you are looking around for hidden treasur

HDU 2732 Leapin&#39; 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

HDU-2732 (Leapin&#39; Lizards) 网络流

网络流真的博大精深 题意: 在一个迷宫中,新进了一批小蜥蜴. 然而因为一些原因,出口被封住了,而且迷宫燃起了大火,现在小蜥蜴们急着离开,想要求助于ACMer们,哈哈-- 把蜥蜴所在的坐标当做一根有高度为k的柱子,现在每有一只蜥蜴跳出格子,格子的柱子高度就会减少一,直到为0,表示这个格子不能在通过蜥蜴. 题目规定,小蜥蜴们可以从当前格子往周围跳出小于等于d距离的长度.当蜥蜴跳出迷宫的边界,就算这只蜥蜴存活下来了,而那些不能逃出去的,就只能等着被烤成烤肉了.现在想要让更多的蜥蜴逃出,求最后剩下的蜥蜴

K - Leapin&#39; Lizards - HDU 2732(最大流)

题意:在一个迷宫里面有一些蜥蜴,这个迷宫有一些柱子组成的,并且这些柱子都有一个耐久值,每当一只蜥蜴跳过耐久值就会减一,当耐久值为0的时候这个柱子就不能使用了,每个蜥蜴都有一个最大跳跃值d,现在想知道有多少蜥蜴不能离开迷宫(跳出迷宫就可以离开了.) 输入描述:输入矩阵的行M和跳跃值D,接着输入两个矩阵(列数自己求),第一个矩阵是每个柱子的耐久值,下面一个矩阵有'L'的表示这个柱子上有一只蜥蜴. 分析:题目明白还是比较容易的,矩阵的点数是20*20,也就400个点,对每个有耐久值的柱子进行拆点,然后

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

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

POJ2711 Leapin&#39; Lizards(最大流)

比较形象的是地图每个点都拆成三个点,这三个点限制流量为0或1,于是再一分为二,这样每个点都被拆成6个点... 其实拆两个点,连容量为柱子高的边,这样就行了.. 这题我掉坑了,“1 lizard was left behind.”..虽然样例都把一切都说了..要注意细节.. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespa

Leapin&#39; Lizards (hdu 2732 最大流)

Leapin' Lizards Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1433    Accepted Submission(s): 586 Problem Description Your platoon of wandering lizards has entered a strange room in the labyr

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

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

hdu2732 (Leapin&#39; Lizards)

题目链接:传送门 题目大意:给你 n,m  n:有几行图,m是一个人最多跳m个曼哈顿距离. 给你两张图,第一张图数字为0表示没有柱子,否则有柱子且只能跳出去 x 次(x为当前字符代表的数字) 第二张图 '.'表示没人,'L'表示当前位置有一个人,问通过柱子之间跳跃最后最少有多少人不能逃出去. 逃出去只能是柱子与边界的最小曼哈顿距离小于等于 m. 题目思路:拆点网络流 首先虚拟源汇点 S,T 其实这道题构图建模不难想,既然某个柱子只能跳 x 次,那就把它拆为两点,连边容量为 x,这样保证合法性.