zoukankan      html  css  js  c++  java
  • 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
    ");
            else printf("%d
    ",l);
        }
        return 0;
    }
  • 相关阅读:
    全网通5X_AL10 非定制版 固件汇总
    system.new.dat解压工具sdat2img
    linux 平台中 Android5.0的更新包中system.new.dat文件的解包
    【 henuacm2016级暑期训练-动态规划专题 A 】Cards
    【BZOJ 1486】 [HNOI2009]最小圈
    【BZOJ 1433】[ZJOI2009]假期的宿舍
    【BZOJ 1412】[ZJOI2009]狼和羊的故事
    【BZOJ 1305】[CQOI2009]dance跳舞
    【Codeforces Round #483 (Div. 2) C】Finite or not?
    【Codeforces Round #482 (Div. 2) C】Kuro and Walking Route
  • 原文地址:https://www.cnblogs.com/wish-all-ac/p/12896859.html
Copyright © 2011-2022 走看看