• 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;
    }
    
  • 相关阅读:
    NoSQL数据库:Redis内存使用优化与存储
    http缓存与cdn相关技术
    sphinx 全文索引
    Elasticsearch7.1中文文档-第一章-入门
    创建一个新的laravel
    mysql数据库的主从同步,实现读写分离
    使用 Swoole 来加速你的 Laravel 应用
    Linux下全局安装composer方法
    Laravel 加载第三方类库的方法
    jquery里把数组转换成json的方法
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13961754.html
Copyright © 2020-2023  润新知