zoukankan      html  css  js  c++  java
  • HDU1733 Escape

    Escape

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 620    Accepted Submission(s): 136


    Problem Description
    Loneknight hates attending class very much. Every time he is attending class, when he feel tiresome with the class, he start planning the shortest path he can escape from the classroom. Therefore, he can escape from classroom so quickly that he is always the first one escape from the classroom after the class finishes. He is very proud of this fact. 

    One day, loneknight is day dreaming in class, and planning the shortest path for escaping. Suddently, an issue come into his mind, if everyone in the classroom want to escape as soon as possible just as loneknight, what will happend? As a kind man, loneknight want to plan a strategy that will let everyone escape from the classroom with minimum time consume. But after dozens of minutes of consideration, loneknight find this problem so difficult for him.

    Now, as the best friend of him, please design a algorithm to solve this problem for him. Note that, at every time unit, everyone can move seperately up, down, left, right one unit, or stay in the old position. In addtion, no one can move to a wall or out of the room, the only way to escape is go through a gate. Moreover, at every time unit, a position can only contain a person, including gates. That means if in time t, a person escape thourgh gate g, no one can go into g in time t, but can go into g in t + 1. Now, it's your job to calculate the minimum time required to escape for everyone.
     


    Input
    The input consists of several test cases. Each test case start with a line containing two number, n, m (1 < n, m <= 16), the rows and the columns of the room. Then n lines follow, each contain exact m characters, representing th type of unitin it. (. for empty place, X for human, # for wall, @ for gate). Input is end with EOF.
     


    Output
    You have to print the shortest time needed for everyone escape from the roomin a single line for each case. (-1 if impossible)
     


    Sample Input
    4 4 .@.. .X.. .... .... 4 4 .@.. .XX. .XX. ..@. 4 4 .@.. .#.. #X#. .#..
     


    Sample Output
    1 2 -1
     


    Source
     
    ****************************************************************

    题目大意:给定一个矩阵,'.'表示空位,'X'表示人,'#'表示墙,'@'表示门,每个位置至多只能站一个人,人不能穿越墙,人能从门中出去。每个人每分钟只能上下左右移动一步,问最少需要多少时间让所有的人出去。

    解题思路:二分时间,拆点。第二次做这道题了,还是那么纠结。

    #include <string.h>
    #include <stdio.h>
    #include <algorithm>
    #define N 180005
    #define E 18000005
    #define INF 0x3f3f3f3f
    #define cha(a,b,c,d) ((a)*m+b+(2*(d)+c)*n*m)
    using namespace std;
    
    int head[N],ed[E],val[E],nxt[E],eid;
    int n,m,pn,zn,nn;
    int tu[20][20],vis[20][20];
    int tox[5]={0,0,1,-1,0};
    int toy[5]={1,-1,0,0,0};
    int gap[N],dist[N];
    int source,sink;
    
    void add_edge(int s,int e,int v,int xv)
    {
        ed[eid]=e;    nxt[eid]=head[s];
        val[eid]=v;   head[s]=eid++;
        ed[eid]=s;    nxt[eid]=head[e];
        val[eid]=xv;  head[e]=eid++;
    }
    
    int dfs(int x,int y)
    {
        vis[x][y]=1;
        if(tu[x][y]==1)
            return 1;
        for(int i=0;i<4;i++)
        {
            int a=x+tox[i],b=y+toy[i];
            if(tu[a][b]<0||vis[a][b])continue;
            if(dfs(a,b))
                return 1;
        }
        return 0;
    }
    
    int ifok(void)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(tu[i][j]!=2)continue;
                memset(vis,0,sizeof(vis));
                if(!dfs(i,j))
                    return 0;
            }
        return 1;
    }
    
    int ISAP(int pos,int cost)
    {
        if(pos==sink)
            return cost;
        int minh=nn-1,lv=cost;
        for(int i=head[pos];~i;i=nxt[i])
        {
            int e=ed[i],v=val[i];
            if(v>0)
            {
                if(dist[e]+1==dist[pos])
                {
                    int d=min(v,lv);
                    d=ISAP(e,d);
                    val[i]-=d;
                    val[i^1]+=d;
                    lv-=d;
                    if(dist[source]>=nn)return cost-lv;
                    if(lv==0)break;
                }
                minh=min(minh,dist[e]);
            }
        }
        if(lv==cost)
        {
            --gap[dist[pos]];
            if(gap[dist[pos]]==0)dist[source]=nn;
            dist[pos]=minh+1;
            gap[dist[pos]]++;
        }
        return cost-lv;
    }
    
    int maxflow(int t)
    {
        memset(head,-1,sizeof(head));
        eid=0;nn=zn*2*t+2;
        source=1;
        sink=cha(0,0,0,t+2);
        for(int h=1;h<=t;h++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    if(tu[i][j]==-1)continue;
                    int a=cha(i,j,0,h);
                    int b=cha(i,j,1,h);
                    add_edge(a,b,1,0);
                }
        for(int h=1;h<t;h++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    if(tu[i][j]==-1||tu[i][j]==1)continue;
                    int a=cha(i,j,1,h);
                    for(int k=0;k<=4;k++)
                    {
                        int x=i+tox[k],y=j+toy[k];
                        if(tu[x][y]==-1)continue;
                        int b=cha(x,y,0,h+1);
                        add_edge(a,b,INF,0);
                    }
                }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(tu[i][j]==2)
                {
                    int b=cha(i,j,0,1);
                    add_edge(source,b,INF,0);
                }
        for(int h=1;h<=t;h++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    if(tu[i][j]==1)
                    {
                        int a=cha(i,j,1,h);
                        add_edge(a,sink,INF,0);
                    }
        memset(dist,0,sizeof(dist));
        memset(gap,0,sizeof(gap));
        int ret=0;
        while(dist[source]<nn)
            ret+=ISAP(source,INF);
        return ret;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(tu,-1,sizeof(tu));
            pn=0;
            zn=n*m;
            for(int i=1;i<=n;i++)
            {
                char str[20];
                getchar();
                scanf("%s",str);
                for(int j=0;j<m;j++)
                {
                    if(str[j]=='.')
                        tu[i][j+1]=0;
                    if(str[j]=='@')
                        tu[i][j+1]=1;
                    if(str[j]=='X')
                        tu[i][j+1]=2,pn++;
                    if(str[j]=='#')
                        zn--;
                }
            }
            if(!ifok())
            {
                puts("-1");
                continue;
            }
            int le=1,ri=n*m,mid;
            while(ri>le)
            {
                mid=(le+ri)/2;
                if(maxflow(mid)==pn)ri=mid;
                else le=mid+1;
            }
            printf("%d\n",ri-1);
        }
    }
    

      

  • 相关阅读:
    JS函数调用的方法
    JS 正则表达式
    JS replace()方法-字符串首字母大写
    JS案例之3——倒计时
    JS案例之2——cycle元素轮播
    jsp自定义标签
    每日记载内容总结23
    maven项目部分知识
    eclipse中整合springMvc,velocity和sitemesh
    eclipse中整合springMvc和velocity
  • 原文地址:https://www.cnblogs.com/Fatedayt/p/2213426.html
Copyright © 2011-2022 走看看