hdu2732 Leapin' 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 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.

题意:有一些蜥蜴进了一个有机关的迷宫,触发了机关,迷宫在坍塌,所以要尽可能多的蜥蜴跳出迷宫,迷宫中有一些柱子,每个柱子有一个数量代表这个柱子只能支撑多少次蜥蜴跳过来,而蜥蜴有一个最大弹跳范围d(哈密顿距离),给出迷宫的每个柱子承受的次数以及蜥蜴的位置还有弹跳范围d,求最少有多少个蜥蜴跳不出来

思路:最大流,建图方法是:对每个柱子的点拆开 i → i‘ 容量为承受次数,i‘ 连其他与这个柱子距离小于d的柱子容量为无限大(这里的无限大设10就已经够了,或者承受次数也可以,反正数据不大),如果这根柱子可以跳出边界了那就 i‘ 连 汇点t 容量无限大或承受次数。 然后对蜥蜴的连边是,源点s连蜥蜴容量为1,蜥蜴连蜥蜴所在的点的柱子 i 容量为1。这样跑一下最大流就得到最大可跳出迷宫的数量,用总数减一下就得到答案。

题目不难,有几个比较坑的点:

1.  输出 如果答案是0或1,lizard不用加s并且后面用was,否则要有s后面用were

2.  输入数据:  题目说d范围0~3,但discuss上有人说数据有d=4的情况;  题目说保证蜥蜴在的点的柱子承受次数不会是0,但实际上有这种情况,而且如果蜥蜴能立刻跳出边界则算他能逃出,否则算不能逃出。。

坑爹囧rz

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1e9;
const double eps = 1e-6;
const int maxn = 2000;
int cas = 1;

struct Edge{
    int from,to,cap,flow;
    Edge() {}
    Edge(int a,int b,int c,int d)
    {
        from=a,to=b,cap=c,flow=d;
    }
};

struct Dinic{
    int n,m,s,t;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];
    void AddEdge(int from,int to,int cap)
    {
        edges.push_back(Edge(from,to,cap,0));
        edges.push_back(Edge(to,from,0,0));
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    void init(int x)
    {
        memset(d,0,sizeof(d));
        edges.clear();
        for(int i=0;i<=x;i++)
            G[i].clear();
    }
    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int> Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty())
        {
            int x=Q.front(); Q.pop();
            for(int i=0;i<G[x].size();i++)
            {
                Edge &e = edges[G[x][i]];
                if(!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    int DFS(int x,int a)
    {
        if(x==t || a==0) return a;
        int flow = 0, f;
        for(int &i=cur[x];i<G[x].size();i++)
        {
            Edge &e=edges[G[x][i]];
            if(d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow += f;
                edges[G[x][i]^1].flow -= f;
                flow += f;
                a -= f;
                if(a==0) break;
            }
        }
        return flow;
    }
    int Maxflow(int s,int t)
    {
        this->s=s; this->t=t;
        int flow = 0;
        while(BFS())
        {
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,INF);
        }
        return flow;
    }
};

Dinic dinic;
int n,m,d;
char g1[25][25],g2[25][25];
inline int id_p(int x,int y)  {return (x*m+y)*2;}
inline int id_l(int x,int y)  {return x*m+y+1000;}
inline bool inside(int x,int y)  {return x>=1 && x<=n && y>=1 && y<=m;}
int s = 0, t = 1999;
inline bool canout(int i,int j)
{
//    cout<<i<<‘ ‘<<j<<endl;
    for(int x=i-d;x<=i+d;x++)
        for(int y=j-d;y<=j+d;y++)
    {
        if(abs(x-i)+abs(y-j)>d || (x==i && y==j)) continue;
        if(!inside(x,y)) return 1;
    }
    return 0;
}
void run()
{
    scanf("%d%d",&n,&d);
    for(int i=1;i<=n;i++)
        scanf("%s",g1[i]+1);
    for(int i=1;i<=n;i++)
        scanf("%s",g2[i]+1);
    m=strlen(g1[1]+1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            g1[i][j]-=‘0‘;
    dinic.init(t);
    int sum = 0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(g1[i][j]==0) continue;
            int u1 = id_p(i,j);
            int u2 = u1^1;
            dinic.AddEdge(u1,u2,g1[i][j]);
            for(int x=i-d;x<=i+d;x++)
                for(int y=j-d;y<=j+d;y++)
            {
                if(abs(x-i)+abs(y-j)>d || (x==i && y==j)) continue;
                if(!inside(x,y))
                {
                    dinic.AddEdge(u2,t,g1[i][j]);
                    goto bk;
                }
                else
                {
                    dinic.AddEdge(u2,id_p(x,y),g1[i][j]);
                }
            }
            bk:;
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(g2[i][j]!=‘L‘)  continue;
            if(g1[i][j]==0 && canout(i,j))  continue;
            sum++;
            dinic.AddEdge(s,id_l(i,j),1);
            dinic.AddEdge(id_l(i,j),id_p(i,j),1);
        }
    int ans = sum - dinic.Maxflow(s,t);
    printf("Case #%d: ",cas++);  //cout<<sum<<‘ ‘;
    if(ans==0)  puts("no lizard was left behind.");
    else if(ans==1)  puts("1 lizard was left behind.");
    else printf("%d lizards were left behind.\n",ans);
}

int main()
{
    #ifdef LOCAL
    freopen("case.txt","r",stdin);
    #endif
    int _;
    scanf("%d",&_);
    while(_--)
        run();
    return 0;
}

hdu2732 Leapin' Lizards (网络流dinic)

时间: 2024-10-09 16:46:52

hdu2732 Leapin' Lizards (网络流dinic)的相关文章

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

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

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

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

hdu2732 (Leapin&#39; Lizards)

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

HDU2732:Leapin&#39; 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 li

【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<

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最多可以支持

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

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