• 题目分享L 二代目


    题意:有一个X*Y的房间,‘X’代表墙壁,‘D’是门,‘.’代表人。这个房间着火了,人要跑出去,但是每一个时间点只有一个人可以从门出去。
    问最后一个人逃出去的最短时间,如果不能逃出去,输出impossible。

    分析:因为每个时刻每扇门只能有一个人通过,所以联想到二分图

    一边应该是p个人的位置,另一边应该是n*m个每个时刻的d扇门

    因为只要找到每个人到达每扇门的最短距离所需花费的时间

    其以后的所有时刻都是可以到达的

    所以要把每个人与每扇门直接最短时间及其以后全部连边,因为最长也就是n*m秒,所以连到n*m即可

    这里我就卡了很久因为不知道如何求p个人到d扇门的距离

    开始用了各种map之类

    后来看了题解才发现只需要一遍bfs求出每扇门到达n*m所有节点的距离,然后mapp[i][p[j].x][p[j].y]其实就是dis[i][j]了

    代码稍微有一点不好写

    不过看肯定能看明白

    void chuli()
    {
        int d_cnt=d.size(),p_cnt=p.size(),ans=0;;
        memset(girl,-1,sizeof(girl));
        for(int i=0;i<n*m*d_cnt;i++)
        {
            memset(vis,0,sizeof(vis));
            ans+=dfs(i);
            if(ans==p_cnt)
            {
                printf("%d
    ",i/d_cnt+1);
                return;
            }
        }
        printf("impossible
    ");
        return ;
    }

    这里可能会稍微有点疑问

    为什么要写i/d_cnt+1之类的

    其实我们门那边的节点是这样的

    d0t0(0号门,第0时刻)d1t0,d2t0...dnt0,d1t1,d1t2...

    而众所周知,这题是求最大匹配,那么如果我们用了前i个就可以使所有人都逃出来,那么肯定就不需要用后面的了

    那么显然,第i个点对应的时间就是i/d_cnt+1

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    
    const int maxn=2e1+1;
    const int maxm=3e4+1;
    
    struct Node
    {
        int x,y;
        Node(){}
        Node(int X,int Y){x=X,y=Y;}
    };
    
    int mapp[maxm][maxn][maxn];
    int xx[4]={0,1,0,-1};
    int yy[4]={1,0,-1,0};
    char a[maxn][maxn];
    vector<Node> p;
    vector<Node> d;
    vector<int> e[maxm];
    int girl[maxm];
    bool vis[maxm];
    int n,m;
    
    int dfs(int x)
    {
        for(int i=0;i<e[x].size();i++)
        {
            int v=e[x][i];
            if(!vis[v])
            {  
                vis[v]=1;
                if(girl[v]==-1||dfs(girl[v]))
                {
                    girl[v]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    void bfs(int x,int dis[maxn][maxn])
    {
        queue<Node> q;
        dis[d[x].x][d[x].y]=0;
        q.push(d[x]);
        while(!q.empty())
        {
            Node now=q.front();q.pop();
            for(int i=0;i<4;i++)
            {
                int nowx=xx[i]+now.x,nowy=yy[i]+now.y;
                if(nowx>=0&&nowx<n&&nowy>=0&&nowy<m&&a[nowx][nowy]=='.'&&dis[nowx][nowy]==-1)
                {
                    dis[nowx][nowy]=dis[now.x][now.y]+1;
                    q.push(Node(nowx,nowy));
                }
            }
        }
    }
    
    void chuli()
    {
        int d_cnt=d.size(),p_cnt=p.size(),ans=0;;
        memset(girl,-1,sizeof(girl));
        for(int i=0;i<n*m*d_cnt;i++)
        {
            memset(vis,0,sizeof(vis));
            ans+=dfs(i);
            if(ans==p_cnt)
            {
                printf("%d
    ",i/d_cnt+1);
                return;
            }
        }
        printf("impossible
    ");
        return ;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            d.clear();p.clear();
            for(int i=0;i<n;i++)
            {
                char ch=getchar();
                for(int j=0;j<m;j++)
                {
                    a[i][j]=getchar();
                    if(a[i][j]=='D') d.push_back(Node(i,j));
                    else if(a[i][j]=='.') p.push_back(Node(i,j));
                }
            }
            int d_cnt=d.size(),p_cnt=p.size();
            if(!p_cnt)
            {
                printf("0
    ");
                continue;
            }
            memset(mapp,-1,sizeof(mapp));
            for(int i=0;i<d_cnt;i++) bfs(i,mapp[i]);
            for(int i=0;i<n*m*d_cnt;i++) e[i].clear();
            for(int i=0;i<d_cnt;i++)
                for(int j=0;j<p_cnt;j++)
                    if(mapp[i][p[j].x][p[j].y]!=-1)
                        for(int k=mapp[i][p[j].x][p[j].y];k<=n*m;k++)
                            e[(k-1)*d_cnt+i].push_back(j);
            chuli();
        }
        return 0;
    }
  • 相关阅读:
    unexpected inconsistency;run fsck manually esxi断电后虚拟机启动故障
    centos 安装mysql 5.7
    centos 7 卸载mysql
    centos7 在线安装mysql5.6,客户端远程连接mysql
    ubuntu 14.04配置ip和dns
    centos7 上搭建mqtt服务
    windows eclipse IDE打开当前类所在文件路径
    git 在非空文件夹clone新项目
    eclipse中java build path下 allow output folders for source folders 无法勾选,该如何解决 eclipse中java build path下 allow output folders for source folders 无法勾选,
    Eclipse Kepler中配置JadClipse
  • 原文地址:https://www.cnblogs.com/lin4xu/p/12896653.html
Copyright © 2020-2023  润新知