Evacuation,题解

题目:

题意:

  有人,门(只有边上有,且1s只能出去一个人),和墙,每s人可移动一个格子,问多少秒所有人可以逃出,逃不出输出“impossible”

分析:

  首先,我们先想着样一个问题,如果这个人在某一秒可以到达了这个们,他将可以在这1s之后的任一没人通过此门的时刻出门。而且题意说每个门每一刻只能使1人通过,那么我们可以直接把门分成好多门(1s一个,当然时间有上线),然后让人和这些门去匹配就好了,看一下第几秒可以人都匹配上就好了,当然我们加一个二分不要一个一个跑了,最后复杂度:10(二分)*10*10(人)*10*10(人)*44(门)*100(时间)(有些估算的较大),有点大,不过还是可以的,毕竟这样求匹配的常熟是很小的。当然有人写的是用D去匹配.然后不用二分了,但是这样的复杂度更大了,它是10*10(人)*44(门)*100(时间)*44(门)*100(时间),而且常数可能也大了。最后就是代码。

  

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
char ch[13][13];
const int maxn=12*12*44*100+10;
struct E{
    int to;
    int next;
    int val;
}ed[maxn];
int head[maxn],ma[maxn],tot;
bool vis[13][13];
void J(int a,int b,int c){
    ed[++tot].to=b;
    ed[tot].val=c;
    ed[tot].next=head[a];
    head[a]=tot;
}
struct Node{
    int x,y,t;
    Node(){}
    Node(int a,int b,int c){x=a;y=b;t=c;}
};
int x,y;
queue<Node> qu;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int M1(int a,int b){return y*(a-1)+b;}
int M2(int a,int b,int t){return (M1(a,b)-1)*100+t;}
void JIA(int a,int b,int nx,int ny,int t){
    for(int i=t;i<=100;i++)
        J(M1(a,b),M2(nx,ny,i),i);
}
void Bfs(int a,int b){
    memset(vis,0,sizeof(vis));
    vis[a][b]=1;
    qu.push(Node(a,b,0));
    while(!qu.empty()){
        Node js=qu.front();
        qu.pop();
        for(int i=0;i<4;i++){
            int nx=js.x+dx[i],ny=js.y+dy[i];
            if(nx>=1&&nx<=x&&ny>=1&&ny<=y&&!vis[nx][ny]&&ch[nx][ny]=='.'){
                vis[nx][ny]=1;
                qu.push(Node(nx,ny,js.t+1));
            }
            if(nx>=1&&nx<=x&&ny>=1&&ny<=y&&!vis[nx][ny]&&ch[nx][ny]=='D'){
                vis[nx][ny]=1;
                JIA(a,b,nx,ny,js.t+1);
            }
        }
    }
}
bool vis2[maxn];
bool Dfs(int x,int t){
    for(int i=head[x];i;i=ed[i].next){
        if(vis2[ed[i].to]||ed[i].val>t) continue;
        vis2[ed[i].to]=1;
        if(ma[ed[i].to]==0||Dfs(ma[ed[i].to],t)){ma[ed[i].to]=x;return 1;}
    }
    return 0;
}
bool pd(int t){
    memset(ma,0,sizeof(ma));
    for(int i=1;i<=x;i++)
        for(int j=1;j<=y;j++)
            if(ch[i][j]=='.'){
                memset(vis2,0,sizeof(vis2));
                if(!Dfs(M1(i,j),t)) return 0;
            }
    return 1;
}
int main(){
    int t;
    scanf("%d",&t);
    for(int jsjs=1;jsjs<=t;jsjs++){
        scanf("%d%d",&x,&y);
        memset(head,0,sizeof(head));
        tot=0;
        for(int i=1;i<=x;i++) for(int j=1;j<=y;j++) scanf(" %c",&ch[i][j]);
        for(int i=1;i<=x;i++) for(int j=1;j<=y;j++) if(ch[i][j]=='.') Bfs(i,j);
        int l=0,r=100;
        while(l<=r){
            int mid=(l+r)/2;
            if(pd(mid)) r=mid-1;
            else l=mid+1;
        }
        if(l==101) printf("impossible\n");
        else printf("%d\n",l);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wish-all-ac/p/12896859.html