HDU 2732&&POJ 2711 Leapin' Lizards 【最大流Dinic】

来源:互联网 发布:淘宝店铺无线端网址 编辑:程序博客网 时间:2024/06/01 08:42


Leapin' Lizards

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

Problem Description

Your platoon of wanderinglizards has entered a strange room in the labyrinth you are exploring. As youare looking around for hidden treasures, one of the rookies steps on aninnocent-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 torage below... Leave no lizard behind! Get as many lizards as possible out ofthe room, and report the number of casualties.
The pillars in the room are aligned as a grid, with each pillar one unit awayfrom the pillars to its east, west, north and south. Pillars at the edge of thegrid are one unit away from the edge of the room (safety). Not all pillarsnecessarily have a lizard. A lizard is able to leap onto any unoccupied pillarthat is within d units of his current one. A lizard standing on a pillar withinleaping distance of the edge of the room may always leap to safety... butthere's a catch: each pillar becomes weakened after each jump, and will sooncollapse and no longer be usable by other lizards. Leaping onto a pillar doesnot cause it to weaken or collapse; only leaping off of it causes it to weakenand eventually collapse. Only one lizard may be on a pillar at any given time.

 

 

Input

The input file will begin witha line containing a single integer representing the number of test cases, whichis at most 25. Each test case will begin with a line containing a singlepositive integer n representing the number of rows in the map, followed by asingle non-negative integer d representing the maximum leaping distance for thelizards. Two maps will follow, each as a map of characters with one row perline. The first map will contain a digit (0-3) in each position representingthe 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' forevery position where a lizard is on the pillar and a '.' for every emptypillar. There will never be a lizard on a position where there is no pillar.Eachinput 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 asingle line containing the number of lizards that could not escape. The formatshould 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 leftbehind.

Case #2: no lizard was leftbehind.

Case #3: 3 lizards were leftbehind.

Case #4: 1 lizard was leftbehind.



【题意】


给出地图的行数,以及每次蜥蜴能跳的最远距离。然后给出n行(第一张图),表示每个点上是否有柱子,有的话柱子的高度为多少。接下来n行为第二张图,表示每个点上是否有蜥蜴。蜥蜴只能停留在石柱上,且如果蜥蜴从一根柱子上跳出了地图,那么这根柱子的高度会减一,高度为0即消失,而蜥蜴在柱子间跳跃,柱子的高度不变,问最小有多少只蜥蜴不能跳出地图。


【思路】


转化一下,能够跳出地图的蜥蜴最大数量即最大流,那么我们需要考虑的是如何建图。


先需要给每个点编号,设tot为总格点数目,那么从0~tot-1编号,并设定源点ss为2*tot+1,汇点tt为ss+1。


如果某个点i有柱子,那么从i->(i+tot)建边,容量为柱子高度。如果某个点i有蜥蜴,那么从ss->i建边。如果蜥蜴能从柱子i跳到柱子j,那么从(i+tot)->j建边,容量为1。如果蜥蜴能从柱子i跳到地图外,那么从(i+tot)->tt建边,容量为INF。


建边完毕后跑一个Dinic最大流,最后相减得出结果,注意一下输出格式即可。



#include <cstdio>#include <vector>#include <queue>#include <cstring>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define rush() int T;scanf("%d",&T);while(T--)typedef long long ll;const int maxn = 1005;const ll mod = 1e9+7;const int INF = 0x3f3f3f;const double eps = 1e-9;int n,m,d,ss,tt,cnt;int dis[maxn];int head[maxn];//int cur[maxn];struct node{    int v,w,next;}e[maxn*maxn];struct point{    int x,y,height;    bool flag;}p[maxn];void init(){    cnt=0;    mst(head,-1);}void add(int u,int v,int w){    e[cnt].v=v;    e[cnt].w=w;    e[cnt].next=head[u];    head[u]=cnt++;}bool jump(const point &a,const point &b){    int len=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);    if(len<=d*d) return true;    return false;}bool out(const point &a){    if(a.x-d<0||a.x+d>=n||a.y-d<0||a.y+d>=m)        return true;    return false;}bool bfs(){    mst(dis,-1);    queue<int>q;    q.push(ss);    dis[ss]=0;    while(q.size())    {        int u=q.front();        q.pop();        if(u==tt) return true;        for(int i=head[u];~i;i=e[i].next)        {            int v=e[i].v;            if(dis[v]==-1&&e[i].w)            {                dis[v]=dis[u]+1;                q.push(v);            }        }    }    return false;}int dfs(int u,int low){    if(u==tt) return low;    int ret=0;    for(int i=head[u];~i;i=e[i].next)    {        int v=e[i].v;        int w=e[i].w;        if(w&&dis[v]==dis[u]+1)        {            int add=dfs(v,min(low-ret,w));            e[i].w-=add;            e[i^1].w+=add;            ret+=add;            if(ret==low) return ret;        }    }    if(ret==0) dis[u]=0;    return ret;}char s[maxn];int main(){    int cas=1;    rush()    {        int tot=0,sum=0;        init();        scanf("%d%d",&n,&d);        for(int i=0;i<n;i++)        {            scanf("%s",s);            m=strlen(s);            for(int j=0;j<m;j++)            {                p[tot].x=i;                p[tot].y=j;                p[tot++].height=s[j]-'0';            }        }        tot=0;        for(int i=0;i<n;i++)        {            scanf("%s",s);            for(int j=0;j<m;j++)            {                if(s[j]=='L') p[tot].flag=true;                else p[tot].flag=false;                tot++;            }        }        ss=tot*2+1;        tt=ss+1;        for(int i=0;i<tot;i++)        {            if(p[i].height)            {                add(i,i+tot,p[i].height);                add(i+tot,i,0);                if(out(p[i]))                {                    add(i+tot,tt,INF);                    add(tt,i+tot,0);                }                if(p[i].flag)                {                    add(ss,i,1);                    add(i,ss,0);                    sum++;                }            }            for(int j=0;j<tot;j++)            {                if(i==j) continue;                if(p[j].height&&jump(p[i],p[j]))                {                    add(i+tot,j,INF);                    add(j,i+tot,0);                }            }        }        int ans=0;        while(bfs())        {            //memcpy(cur,head,sizeof(head));            ans+=dfs(ss,INF);        }        ans=sum-ans;        printf("Case #%d: ",cas++);        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);        }    }    return 0;}




0 0