lightoj 1405 The Great Escape(网络流+建图)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37943488/article/details/82219304

1405 - The Great Escape

    PDF (English) Statistics Forum
Time Limit: 5 second(s) Memory Limit: 32 MB

Walter White finally discovered the medicine for a dangerous disease. That's why he is in danger, because some people are targeting him to get the formula. So, now he and his co-workers have to leave the city.

Assume that the city can be modeled as an M x N grid, where a cell containing a '*' means that a co-worker lives in that place, a cell containing a '.' means it's empty.

So, Walter informed all of them by phone to leave the city at once and he has laid down a rule that no one will cross path in their way out of the city. Since if two or more persons meet at same cell (even in the boundary cells), there is a big possibility that they all might get caught. Walter doesn't want that, so he needs to know whether all of them can get out of the city. So, he asked you to help him.

For simplicity, assume that if one person reaches any of the border cells of the grid, he is considered to be out of the city. And from any cell, a person can move only to its four adjacent cells (north, south, east or west).

Fig 1: Position of the persons

Fig 2: Escape Paths

For example, for the given 7 x 6 grid, the colored circles show the position of the persons who are escaping (fig 1). And a feasible solution is shown in fig 2.

Input

Input starts with an integer T (≤ 20), denoting the number of test cases.

Each case starts with a line containing two integers M and N (1 ≤ M, N ≤ 100). Each of the next M lines contains N characters denoting the map. Each characters is either '.' or '*'. Total number of persons in a map will be at most 2*(M+N).

Output

For each case, print the case number and 'yes' if it's possible for them to get out of the city maintaining the restrictions. Otherwise print 'no'.

Sample Input

Output for Sample Input

3

7 6

..*...

.*.*..

..*.*.

***..*

.....*

..**..

....*.

4 10

***..***.*

*.**.***.*

..*..*..**

.**.*.*.**

4 10

***..***.*

*.**.***.*

..*..*...*

.**.*.*.**

Case 1: yes

Case 2: no

Case 3: yes

 题目大意:给一个地图,地图上的*号表示人,人要逃出这个地图,'.'表示可以走的地方,每个人走的路径不能有重复的地方,问是否所有人都能逃出去。

对于每一个人,将它与源点连一条容量为1的边,对于每一个点,将其拆成两个点,连一条容量为1的边,表示只能走一次,对于那些在边界的点,将它与汇点相连,表示这个点可以出去,对于每一个点,将它与上下左右四个方向的点相连,表示能走。然后跑一遍最大流

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=2e4+100;
const int maxm=2000010;
const int inf=0x3f3f3f3f;
struct Node
{
    int to;
    int capa;
    int next;
}edge[maxm];
int n,m;
int cnt;
int nv;
int source,sink;
int head[maxn];
char map[110][110];
int dep[maxn];
int dirx[]={0,1,0,-1};
int diry[]={1,0,-1,0};
void init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
    return;
}
void add(int u,int v,int capa)
{
    edge[cnt].to=v;
    edge[cnt].capa=capa;
    edge[cnt].next=head[u];
    head[u]=cnt++;
    edge[cnt].to=u;
    edge[cnt].capa=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
    return;
}
bool bfs()
{
    queue<int> que;
    que.push(source);
    memset(dep,-1,sizeof(dep));
    dep[source]=0;
    while(!que.empty())
    {
        int node=que.front();
        que.pop();
        for(int i=head[node];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].capa>0&&dep[v]==-1)
            {
                dep[v]=dep[node]+1;
                if(v==sink) return true;
                que.push(v);
            }
        }
    }
    return dep[sink]!=-1;
}
int dfs(int node,int minn)
{
    if(node==sink||minn==0)
    {
        return minn;
    }
    int r=0;
    for(int i=head[node];~i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(dep[v]==dep[node]+1&&edge[i].capa>0)
        {
            int tmp=dfs(v,min(edge[i].capa,minn));
            if(tmp>0)
            {
                edge[i].capa-=tmp;
                edge[i^1].capa+=tmp;
                r+=tmp;
                minn-=tmp;
                if(!minn) break;
            }
        }
    }
    if(!r) dep[node]=-1;
    return r;
}
int dinic()
{
    int maxflow=0;
    while(bfs())
    {
        maxflow+=dfs(source,inf);
    }
    return maxflow;
}
int getIndex(int x,int y)
{
    return (x-1)*m+y;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int test;
    scanf("%d",&test);
    for(int cas=1;cas<=test;cas++)
    {
        init();
        scanf("%d%d",&n,&m);
        source=0;
        sink=n*m*2+10;
        getchar();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",map[i]+1);
        }
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(i==1||i==n||j==1||j==m)
                {
                    add(getIndex(i,j)+n*m,sink,1);
                }
                add(getIndex(i,j),getIndex(i,j)+n*m,1);
                for(int k=0;k<4;k++)
                {
                    int x=i+dirx[k];
                    int y=j+diry[k];
                    if(x>=1&&x<=n&&y>=1&&y<=m)
                    {
                        add(getIndex(i,j)+n*m,getIndex(x,y),1);
                    }
                }
                if(map[i][j]=='*')
                {
                    sum++;
                    add(source,getIndex(i,j),1);
                }
            }
        }
        if(dinic()==sum) printf("Case %d: yes\n",cas);
        else printf("Case %d: no\n",cas);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37943488/article/details/82219304