zoukankan      html  css  js  c++  java
  • POJ 3057-Evacuation

    分析

    这个题想了半天。
    最开始想的是不断地BFS,但这样不仅时间复杂度没有保障,而且正确性可能也有问题。
    如果门是固定的,还可以考虑像曾经一个题那么做,但现在不行了,因为门不仅不固定,而且还有很多个。
    但有一个性质可以考虑,就是每扇门在某一时刻只能走出一个人。
    不难想到二分图匹配。

    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=15,M=1e5+10;
    struct Node{
        int x,y;
        Node(){}
        Node(int a,int b){
            x=a;y=b;
        }
    };
    struct Edge{
        int to,nxt;
    }e[M*100];
    int h[10*M],idx;
    void Ins(int a,int b){
        e[++idx].to=b;e[idx].nxt=h[a];h[a]=idx;
    }
    char map[N][N],vis[M];
    int match[M*10],dis[N][N],d[N][N][N][N],n,m;
    vector <Node > pi,di;
    void bfs(int x,int y){
        int dx[]={1,-1,0,0};
        int dy[]={0,0,1,-1};
        memset(dis,-1,sizeof(dis));
        dis[x][y]=0;
        queue<Node > q;
        q.push(Node(x,y));
        while(!q.empty()){
            Node u=q.front();q.pop();
            for(int i=0;i<4;i++){
                int ux=u.x+dx[i];
                int uy=u.y+dy[i];
                if(ux>=0&&uy>=0&&ux<n&&uy<m){
                    if(map[ux][uy]=='.'&&dis[ux][uy]==-1){
                        dis[ux][uy]=dis[u.x][u.y]+1;
                        d[x][y][ux][uy]=dis[ux][uy];
                        q.push(Node(ux,uy));
                    }
                }
            }
        }
    }
    bool dfs(int x){
        vis[x]=1;
        for(int i=h[x];i;i=e[i].nxt){
            int v=e[i].to;
            if(match[v]==-1||!vis[match[v]]&&dfs(match[v])){
                match[v]=x;
                match[x]=v;
                return 1;
            }
        }
        return 0;
    }
    int sum(int x){
        for(int i=0;i<pi.size();i++)
            for(int j=0;j<di.size();j++){
                int px=pi[i].x,py=pi[i].y;
                int dx=di[j].x,dy=di[j].y;
                if(d[dx][dy][px][py]<=x){
                    Ins(x*di.size()+j,(n*m+10)*di.size()+10+i);
                    Ins((n*m+10)*di.size()+10+i,x*di.size()+j);
                }
            }
        int tot=0;
        for(int i=0;i<di.size();i++){
            int u=i+x*di.size();
            if(match[u]==-1){
                memset(vis,0,sizeof(vis));
                if(dfs(u))tot++;
            }
        }
        return tot;
    }
    void calc(){
        memset(match,-1,sizeof(match));
        int tot=0;
        for(int i=0;i<=m*n+3;i++){
            tot+=sum(i);
            if(tot>=pi.size()){
                printf("%d
    ",i);
                return ;
            }
        }
        printf("impossible
    ");
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            idx=0;
            pi.clear();di.clear();
            memset(d,0x3f,sizeof(d));
            memset(h,0,sizeof(h));
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++)
                scanf("%s",map[i]);
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(map[i][j]=='D'){
                        di.push_back(Node(i,j));
                        bfs(i,j);                    
                    }else if(map[i][j]=='.'){
                        pi.push_back(Node(i,j));
                    }
                }
            }
            calc();
        }
    }
    
  • 相关阅读:
    30、深入浅出MFC学习笔记,多线程
    29、深入浅出MFC学习笔记,多重文件和视图
    5、程序设计实践读书笔记
    6、C++ Primer 4th 笔记,标准IO库(1)
    SQL Server流程控制 7,Try...Catch 语句
    TSQL:流程控制 4,Case 语句
    SQL Server事务处理(Tansaction)与锁(Lock)
    SQL Server9,流程控制 Execute 语句(*)
    SQL Server流程控制 2,If...Else 语句
    SQL Server流程控制 1,Begin...End 语句
  • 原文地址:https://www.cnblogs.com/anyixing-fly/p/12899432.html
Copyright © 2011-2022 走看看