HDU--杭电--2732//POJ--2711--Leapin' Lizards--网络流

Leapin‘ Lizards

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1537    Accepted Submission(s): 626

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.

题意:要你求出在nxm的地图中的蜥蜴尽量逃离之后剩下的最小量,蜥蜴出了地图边缘就算逃离成功,每个柱子如果上面有蜥蜴,那么蜥蜴离开这个柱子的时候柱子高度会减一,高度为0的时候蜥蜴就不能跳到这个上面,每个case输入n和D,D是蜥蜴能跳跃的最大距离,然后是两个n行的地图,因为不知道m大小,所以用%s输入然后计算,地图1中表示柱子的初始高度,地图2中“L”表示这个位置的柱子上有一只蜥蜴

题解:还是老办法,假设原点S和汇点T,每个蜥蜴连接原点S,边权值是1表示一只蜥蜴入场,然后每个高度大于0的柱子全部再设置一个流出点,因为题目中限制流量的是柱子,也就是点,我们把这个点作为这个流量的流入点,再设置一个流出点,连接它们并使边权值为这个点的高度,这样就能把限制从点转移到边了,我是流出点等于流入点加400,因为地图最大的点的数量是400,然后能出边界的且柱子高度大于0的点,全部连接汇点T,边权值是MAX,然后是可以跳跃的柱子之间连接起来,边权值也是MAX,MAX是一个极大值,自己尽量设大点,用来表示这是一条通路就行。

注意:网上各种喊坑:

1、输出那里看好了,英语单词的大考验--!输出的剩余数量如果是no或者1则用单数形式,大于1则用复数形式(单数 lizard was 复数 lizards were);

2、题目说柱子高度d的范围是0<=d<=3,但是有更大的值,也就是说会超过3,这里影响不大,是那些屌丝抱怨着喊出来的;

3、每个高度大于0的柱子作为流入点并额外再设置一个流出点,则柱子与柱子满足跳跃距离是要保证流出点对流入点作边,不然对于这么多代码,混乱一块则让你纠结到死;

4、这里的距离我也不知道作者是怎么想的,竟然是两点的x轴距离加上y轴距离的和;

5、这里对于第一次做这种由点来限制流量的网络流题目,看到别人博客写着“分割点”,尼玛啵什么是分割点又不讲,留下来的就是一堆在你眼里类似乱码的代码,这里我告诉你我的理解,分割点是对于由点来限制流量的情况下把这个点分成两个点,然后相连的这条边就设置为这个点的值,这样这限制流量的就不是点而是边了,这样你学过的那些东东就又能用了,嘿嘿~~~不知道对不对,但是这样理解不会有错。。

对于类似我这种懒于看字的人,我画个图,相信有点用。。

#include <iostream>

#include <cstdio>

#include <cstring>

#include <queue>

#define MAX 1000000001

#define Max(a,b) a>b?a:b

#define Min(a,b) a<b?a:b

#define M 1111

using namespace std;

int D,S=0,T,num,cas=1;

char s1[22][22],s2[22][22];//两个地图

struct node

{

    int to,val,next;

}s[M*M];

int snum,dnum=400,hand[M],dis[M],q[M];

void setit(int from,int to,int
val
)//这个线性建立点的我就不多说了,前面博客有

{

s[snum].to=to;

s[snum].val=val;

s[snum].next=hand[from];

hand[from]=snum++;

s[snum].to=from;

s[snum].val=0;

s[snum].next=hand[to];

hand[to]=snum++;

}

bool pd(int x,int y,int
n,int l
)//判断当前坐标移动D之后是否出界

{

    if(x<=D||y<=D)return
true;

    if(n+1-x<=D||l+1-y<=D)return
true;

    return false;

}

bool pddis(int x1,int y1,int
x2,int y2
)//判断两坐标的x距离与y距离之和是否小于D,即他们的距离蜥蜴是否能跳跃

{

    int a,b;

a=x1-x2;

b=y1-y2;

a=(a>0?a:-a);

b=(b>0?b:-b);

    if(a+b<=D)return
true;

    return false;

}

bool bfs()//dinic算法中bfs分层,前面博客已经写过详细的了

{

    int i,j,k,l,cur,qian,hou;

memset(dis,-1,sizeof(dis));

qian=hou=0;

q[qian++]=S;

dis[S]=0;

    while(qian!=hou)

{

cur=q[hou++];

        if(hou>=M)hou=0;

        for(i=hand[cur];i!=-1;i=s[i].next)

{

k=s[i].to;

            if(s[i].val>0&&dis[k]==-1)

{

dis[k]=dis[cur]+1;

q[qian++]=k;

                if(qian>=M)qian=0;

                if(k==T)return
true
;

}

}

}

    return false;

}

int dfs(int x,int flow)//同上,前面写过详细的了

{

    int i,j,k,l,cost=0;

    if(x==T)return flow;

    for(i=hand[x];i!=-1;i=s[i].next)

{

k=s[i].to;

        if(s[i].val>0&&dis[x]+1==dis[k])

{

l=dfs(k,Min(flow-cost,s[i].val));

            if(l>0)

{

cost+=l;

s[i].val-=l;

s[i^1].val+=l;

}else dis[k]=-1;

}

}

    return cost;

}

void dinic()//同上

{

    int i,j,k,l=num;

    while(bfs())

{

k=dfs(S,MAX);

l-=k;

}

    if(l==0)printf("Case
#%d: no lizard was left behind.\n",cas++);//这里就是我说的第一个坑点

    else printf("Case #%d: %d %s left behind.\n",cas++,l,l==1?"lizard
was":"lizards were"
);

}

int main (void)

{

    int t,n,m,i,j,k,l,x,y,q;

scanf("%d",&t);

    while(t--&&scanf("%d%d",&n,&D))

{

snum=0;

num=0;

memset(hand,-1,sizeof(hand));

        for(i=0;i<n;i++)

{

scanf("%s",s1[i]);//输入第一个地图

l=strlen(s1[i]);//不好意思,这一句忘记删除了

}

T=1001;

        for(i=0;i<n;i++)

{

scanf("%s",s2[i]);输入第二个地图

            for(j=0;j<l;j++)

{

q=i*l+j+1;//把地图上的点编号成1到nXm

                if(s2[i][j]==‘L‘)

{

num++;

setit(S,q,1);//连接原点S跟当前点

}

                if(s1[i][j]!=‘0‘)

{

setit(q,q+dnum,s1[i][j]-‘0‘);//dnum=400,q+dnum是表示q的流出点,而q直接作为流入点

                    for(k=i*l+j;k>0;k--)

{

x=(k-1)/l;//把编号分解成坐标

y=k-x*l-1;

                        if(s1[x][y]!=‘0‘&&pddis(i,j,x,y))//判断(x,y)高度和它与(i,j)的距离

{

setit(q+dnum,k,MAX);//两个柱子都能供蜥蜴跳跃且距离可以,则(i,j)流出点连接(x,y)流入点

setit(k+dnum,q,MAX);//(x,y)流出点连接(i,j)流入点

}

}

                    if(pd(i+1,j+1,n,l))//判断移动D距离能否出界

{

setit(q+dnum,T,MAX);//能出界则当前点的流出点连接汇点T

}

}

}

}

dinic();

}

    return 0;

}

照这样每天都有收货的过下去,至少自己更自信~~

HDU--杭电--2732//POJ--2711--Leapin' Lizards--网络流

时间: 2024-10-27 05:36:01

HDU--杭电--2732//POJ--2711--Leapin' Lizards--网络流的相关文章

『ACM C++』HDU杭电OJ | 1415 - Jugs (灌水定理引申)

今天总算开学了,当了班长就是麻烦,明明自己没买书却要带着一波人去领书,那能怎么办呢,只能说我善人心肠哈哈哈,不过我脑子里突然浮起一个念头,大二还要不要继续当这个班委呢,既然已经体验过就可以适当放下了吧,用心在自己的研究上.晚上级会开完也就八点多了,开始打打题,今天在HDU杭电的ACM集训题看到一个奇葩的题,前来献上. 今日推荐: <全球风暴> 一部宇宙航空和地球气候片的良心佳作,后期特效建模都是特别杠杠的大片,不会让你失望的哟,我已经三刷了哈哈哈.这部片在爱奇艺有上线,有兴趣的朋友可以看看鸭.

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

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

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杭电2066【dijkstra算法】

http://acm.hdu.edu.cn/showproblem.php?pid=2066 Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景--草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女--眼看寒假就快到了,这么一大段时间,可不

一个人的旅行 HDU杭电2066【dijkstra算法 || SPFA】

http://acm.hdu.edu.cn/showproblem.php? pid=2066 Problem Description 尽管草儿是个路痴(就是在杭电待了一年多,竟然还会在校园里迷路的人.汗~),但是草儿仍然非常喜欢旅行,由于在旅途中 会遇见非常多人(白马王子.^0^),非常多事,还能丰富自己的阅历.还能够看漂亮的风景--草儿想去非常多地方.她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋.去纽约纯粹看雪景.去巴黎喝咖啡写信.去北京探望孟姜女--眼看寒假就快到了,这么一大段

杭电 1272 POJ 1308 小希的迷宫

这道题是我学了并查集过后做的第三个题,教我们的学姐说这是并查集的基础题,所以有必要牢牢掌握. 下面就我做这道题的经验,给大家一些建议吧!当然,我的建议不是最好的,还请各位大神指出我的错误来,我也好改正. 1.题目概览 这道题是杭电1272,POJ 1308如果写好了代码可以试一试. 小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s

Sum It Up POJ 1564 HDU 杭电1258【DFS】

Problem Description Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t=4, n=6, and the list is [4,3,2,2,1,1], then there are four different sums that equal 4: 4,3

畅通project续HDU杭电1874【dijkstra算法 || SPFA】

http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了非常多年的畅通project计划后.最终修建了非常多路.只是路多了也不好,每次要从一个城镇到还有一个城镇时,都有很多种道路方案能够选择,而某些方案要比还有一些方案行走的距离要短非常多.这让行人非常困扰. 如今,已知起点和终点,请你计算出要从起点到终点.最短须要行走多少距离. Input 本题目包括多组数据.请处理到文件结束. 每组数据第一行包括两个正

Choose the best route HDU杭电2680【dijkstra算法】

http://acm.hdu.edu.cn/showproblem.php?pid=2680 Problem Description One day , Kiki wants to visit one of her friends. As she is liable to carsickness , she wants to arrive at her friend's home as soon as possible . Now give you a map of the city's tra

六度分离 HDU杭电1869【dijkstra算法】

http://acm.hdu.edu.cn/showproblem.php?pid=1869 Problem Description 1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一个名为"小世界现象(small world phenomenon)"的著名假说,大意是说,任何2个素不相识的人中间最多只隔着6个人,即只用6个人就可以将他们联系在一起,因此他的理论也被称为"六度分离"理论(six degrees of separation).虽然米尔格兰姆的理论