zoukankan      html  css  js  c++  java
  • BZOJ 4456 [Zjoi2016]旅行者

    题解:分治

    div(a,b,c,d,l,r)

    表示处理在(a,b)(c,d)这个矩形内走,队列(l,r)中询问的答案

    枚举较短中线上的点,求最短路

    如果x,y不再同一侧,那么最短路一定经过中线,处理完毕

    如果在同一侧,那么最短路可能经过也可能不经过中线,所以递归两边处理

    犯过的SB错误:

    把询问分组的时候把原数组覆盖了

    横纵坐标不分

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn=300009;
    const int oo=1000000000;
    
    int n,m,TT;
    int downdist[maxn],rightdist[maxn];
    
    int limx1,limy1,limx2,limy2;
    
    inline int P(int x,int y){
        return (x-1)*m+y;
    }
    inline bool Isinrange(int u){
        int y=(u-1)%m+1;
        int x=(u-y)/m+1;
        return (x>=limx1)&&(x<=limx2)&&(y>=limy1)&&(y<=limy2);
    }
    
    
    int d[maxn];
    int vis[maxn];
    struct HeapNode{
        int v,mindist;
        HeapNode(int x){
            v=x;mindist=d[x];
        }
        bool operator < (const HeapNode &rhs) const{
            return mindist>rhs.mindist;
        }
    };
    priority_queue<HeapNode>q;
    
    void Dijkstra(int s){
        for(int i=limx1;i<=limx2;++i){
            for(int j=limy1;j<=limy2;++j){
                d[P(i,j)]=oo;vis[P(i,j)]=0;
            }
        }
        
        d[s]=0;q.push(HeapNode(s));
        while(!q.empty()){
            HeapNode x=q.top();q.pop();
            int u=x.v;
            if(vis[u])continue;
            vis[u]=1;
            int v;
            v=u+m;
            if(v<=n*m){
                if(d[u]+downdist[u]<d[v]){
                    d[v]=d[u]+downdist[u];
                    q.push(HeapNode(v));
                }
            }
            v=u-m;
            if(v>0){
                if(d[u]+downdist[v]<d[v]){
                    d[v]=d[u]+downdist[v];
                    q.push(HeapNode(v));
                }
            }
            v=u+1;
            if((u%m!=0)){
                if(d[u]+rightdist[u]<d[v]){
                    d[v]=d[u]+rightdist[u];
                    q.push(HeapNode(v));
                }
            }
            v=u-1;
            if(((u-1)%m!=0)){
                if(d[u]+rightdist[v]<d[v]){
                    d[v]=d[u]+rightdist[v];
                    q.push(HeapNode(v));
                }
            }
        }
    }
    
    int qs[maxn];
    int qx1[maxn],qy1[maxn],qx2[maxn],qy2[maxn];
    int ans[maxn];
    int tmpq[maxn];
    
    void DivCon(int upx,int upy,int downx,int downy,int ll,int rr){
        if(ll>rr)return;
        int deltx=downx-upx;
        int delty=downy-upy;
        limx1=upx;limy1=upy;
        limx2=downx;limy2=downy;
    
        int p1=ll,p2=rr;
        if(deltx<=delty){
            int mid=(upy+downy)>>1;
            for(int i=upx;i<=downx;++i){
                Dijkstra(P(i,mid));
                for(int k=ll;k<=rr;++k){
                    int t=qs[k];
                    int a=P(qx1[t],qy1[t]);
                    int b=P(qx2[t],qy2[t]);
                    ans[t]=min(ans[t],d[a]+d[b]);
                }
            }
            for(int k=ll;k<=rr;++k){
                int t=qs[k];
                if(((qy1[t]<=mid)&&(qy2[t]>=mid))||((qy1[t]>=mid)&&(qy2[t]<=mid)))continue;
                if(qy1[t]<=mid){
                    tmpq[p1]=t;++p1;
                }
                if(qy1[t]>=mid){
                    tmpq[p2]=t;--p2;
                }
            }
            for(int i=ll;i<=rr;++i)qs[i]=tmpq[i];
            DivCon(upx,upy,downx,mid-1,ll,p1-1);
            DivCon(upx,mid+1,downx,downy,p2+1,rr);
        }else{
            int mid=(upx+downx)>>1;
            for(int i=upy;i<=downy;++i){
                Dijkstra(P(mid,i));
                for(int k=ll;k<=rr;++k){
                    int t=qs[k];
                    int a=P(qx1[t],qy1[t]);
                    int b=P(qx2[t],qy2[t]);
                    ans[t]=min(ans[t],d[a]+d[b]);
                }
            }
            
            for(int k=ll;k<=rr;++k){
                int t=qs[k];
                if(((qx1[t]<=mid)&&(qx2[t]>=mid))||((qx1[t]>=mid)&&(qx2[t]<=mid)))continue;
                if(qx1[t]<=mid){
                    tmpq[p1]=t;++p1;
                }
                if(qx1[t]>=mid){
                    tmpq[p2]=t;--p2;
                }
            }
            for(int i=ll;i<=rr;++i)qs[i]=tmpq[i];
            DivCon(upx,upy,mid-1,downy,ll,p1-1);
            DivCon(mid+1,upy,downx,downy,p2+1,rr);
        }
    }
    
    
    int main(){
    //    freopen("tourist.in","r",stdin);
    //    freopen("tourist.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i){
            for(int j=1;j<m;++j){
                scanf("%d",&rightdist[P(i,j)]);
            }
        }
        for(int i=1;i<=n-1;++i){
            for(int j=1;j<=m;++j){
                scanf("%d",&downdist[P(i,j)]);
            }
        }
        
        scanf("%d",&TT);
        for(int i=1;i<=TT;++i){
            scanf("%d%d%d%d",&qx1[i],&qy1[i],&qx2[i],&qy2[i]);
        }
        for(int i=1;i<=TT;++i)ans[i]=0x7fffffff;
        for(int i=1;i<=TT;++i)qs[i]=i;
        
        DivCon(1,1,n,m,1,TT);
        
        
        for(int i=1;i<=TT;++i)printf("%d
    ",ans[i]);
        return 0;
    }
    自己还是太辣鸡了
  • 相关阅读:
    5-python基础—获取某个目录下的文件列表(适用于任何系统)
    Automated, Self-Service Provisioning of VMs Using HyperForm (Part 1) (使用HyperForm自动配置虚拟机(第1部分)
    CloudStack Support in Apache libcloud(Apache libcloud中对CloudStack支持)
    Deploying MicroProfile-Based Java Apps to Bluemix(将基于MicroProfile的Java应用程序部署到Bluemix)
    Adding Persistent Storage to Red Hat CDK Kit 3.0 (在Red Hat CDK Kit 3.0添加永久性存储)
    Carve Your Laptop Into VMs Using Vagrant(使用Vagran把您笔记本电脑刻录成虚拟机)
    使用Python生成一张用于登陆验证的字符图片
    Jupyter notebook的安装方法
    Ubuntu16.04使用Anaconda5搭建TensorFlow使用环境 图文详细教程
    不同时区的换算
  • 原文地址:https://www.cnblogs.com/zzyer/p/8598815.html
Copyright © 2011-2022 走看看