zoukankan      html  css  js  c++  java
  • 2020CCPC威海/gym102798 B-Labyrinth 最短路

    2020CCPC威海/gym102798 B-Labyrinth

    题意

    给定一个(n)(m)列的格点图,图中有(k)个黑洞,有(q)次询问,每次询问给出入口((xs,ys))和出口((xt,yt)),问从入口走到出口的最短距离,若无法到达输出(-1),最短距离为走的步数,每一步可以选择上下左右四个方向走。

    (1le n,m le 2cdot 10^5,nmle 2cdot 10^5,0le k le 42)

    分析

    分类讨论一下:

    • 若以入口和出口为顶点构成的矩形中没有黑洞,那么答案即为两点的曼哈顿距离。
    • 若以入口和出口为顶点构成的矩形中有黑洞且存在入口到出口的路径,那么一定存在一条最短路是经过某个黑洞旁边可以走的格点的。

    我们可以把所有黑洞旁边的格点作为起点bfs求最短路,然后更新(ans=min(ans,dis[xs][ys]+dis[xt][yt]))

    Code

    #include<bits/stdc++.h>
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define per(i,n,x) for(int i=n;i>=x;i--)
    #define sz(a) int(a.size())
    #define rson mid+1,r,p<<1|1
    #define pii pair<int,int>
    #define lson l,mid,p<<1
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    const double eps=1e-8;
    const int mod=1e9+7;
    const int N=2e5+10;
    const int inf=1e9;
    int n,m,k,q;
    int xx[]={1,-1,0,0};
    int yy[]={0,0,1,-1};
    vector<vector<int> >a,b,dis[210];
    vector<pii>v;
    bool ck(int x,int y){
        return x>=1&&x<=n&&y>=1&&y<=m;
    }
    int cal(int x1,int y1,int x2,int y2){
        if(x1>x2) swap(x1,x2);
        if(y1>y2) swap(y1,y2);
        return b[x2][y2]-b[x1-1][y2]-b[x2][y1-1]+b[x1-1][y1-1];
    }
    void bfs(int it,pii s){
        queue<pii>q;
        dis[it][s.fi][s.se]=0;
        q.push(s);
        while(!q.empty()){
            pii u=q.front();q.pop();
            for(int i=0;i<4;i++){
                int dx=u.fi+xx[i];
                int dy=u.se+yy[i];
                if(ck(dx,dy)&&!a[dx][dy]&&dis[it][u.fi][u.se]+1<dis[it][dx][dy]){
                    dis[it][dx][dy]=dis[it][u.fi][u.se]+1;
                    q.push(mp(dx,dy));
                }
            }
        }
    }
    int main(){
        //ios::sync_with_stdio(false);
        //freopen("in","r",stdin);
        scanf("%d%d%d%d",&n,&m,&k,&q);
        a.resize(n+5,vector<int>(m+5,0));
        b.resize(n+5,vector<int>(m+5,0));
        vector<pii>hole;
        for(int i=1,x,y;i<=k;i++){
            scanf("%d%d",&x,&y);
            a[x][y]=b[x][y]=1;
            hole.pb(mp(x,y));
        }
        for(pii it:hole){
            for(int i=0;i<4;i++){
                int dx=it.fi+xx[i];
                int dy=it.se+yy[i];
                if(ck(dx,dy)&&!a[dx][dy]) v.pb(mp(dx,dy));
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                b[i][j]+=b[i][j-1]+b[i-1][j]-b[i-1][j-1];
            }
        }
        for(int i=0;i<sz(v);i++){
            dis[i].resize(n+5,vector<int>(m+5,inf));
            bfs(i,v[i]);
        }
        while(q--){
            int xs,ys,xt,yt;
            scanf("%d%d%d%d",&xs,&ys,&xt,&yt);
            if(cal(xs,ys,xt,yt)==0){
                if(xs>xt) swap(xs,xt);
                if(ys>yt) swap(ys,yt);
                printf("%d
    ",xt-xs+yt-ys);
            }else{
                int ans=inf;
                for(int i=0;i<sz(v);i++){
                    ans=min(ans,dis[i][xs][ys]+dis[i][xt][yt]);
                }
                if(ans==inf) ans=-1;
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Linux下环境变量配置错误 导致大部分命令不可以使用的解决办法
    问题1:kafka的message包括那些?
    zabbix4.4
    jdk1.8安装
    linux 环境python3安装
    Zabbix应用监控
    zabbix4.0.21部署
    AtCoder Beginner Contest 187
    Codeforces Round #690 (Div. 3)
    AtCoder Beginner Contest 185
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13961754.html
Copyright © 2011-2022 走看看