zoukankan      html  css  js  c++  java
  • 【ZJOI2016】旅行者

    分治+Dij

    也没想象中的难写,就是有轻微卡常

    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    #include<ext/pb_ds/priority_queue.hpp>
    const int maxn = 20100;
    using std::max;
    using std::min;
    int n,m;
    int dis[maxn],vis[maxn];
    struct P{
        int x,y,dis;
        __attribute__((always_inline)) operator int()const{return (x-1)*m+y;}
        __attribute__((always_inline)) int operator <(const P&b)const{return dis>b.dis;}
    };
    struct Q{P a,b;int ans;}b[100100];
    inline void down(int&x,int y){if(x>y)x=y;}
    struct T{
        P to;
        int nxt,v;
    }way[maxn<<2];
    int h[maxn],num;
    inline void adde(P x,P y,int v){
        way[++num]={y,h[x],v},h[x]=num;
        way[++num]={x,h[y],v},h[y]=num;
    }
    __gnu_pbds::priority_queue<P>q;
    __gnu_pbds::priority_queue<P>::point_iterator iter[maxn];
    inline void run(int x,int y,int x1,int y1,int x2,int y2){
        for(int i=x1;i<=x2;++i)
            for(int j=y1;j<=y2;++j)
                dis[(i-1)*m+j]=1e9,iter[(i-1)*m+j]=q.push({i,j,(int)1e9});
        dis[(x-1)*m+y]=0,q.modify(iter[(x-1)*m+y],{x,y,0});
        while(!q.empty()){
            P t=q.top();q.pop();int Ds = dis[t];
            for(int i=h[t];i;i=way[i].nxt){
                P z = way[i].to;int Z=z;
                if(x1 <= z.x && z.x <= x2 && y1 <= z.y && z.y <= y2 && dis[Z]>Ds+way[i].v){
                    z.dis=dis[Z]=Ds+way[i].v;
                    q.modify(iter[Z],z);
                }
            }
        } 
    }
    inline void solve(int x1,int y1,int x2,int y2,std::vector<Q*>&v){
        if(x1 > x2 || y1 > y2 || v.empty())return ;
        if(x1 == x2 && y1 == y2){
            for(Q*&i:v)i->ans=0;
            return ;
        }
        if(x2-x1 >= y2-y1){
            int mid = x1 + x2 >> 1;
            for(int i=y1;i<=y2;++i){
                run(mid,i,x1,y1,x2,y2);
                for(Q*&i:v)down(i->ans,dis[i->a]+dis[i->b]);
            }
            std::vector<Q*> v1,v2;
            for(Q*i:v){
                if(max(i->a.x,i->b.x) < mid)v1.emplace_back(i);
                if(min(i->a.x,i->b.x) > mid)v2.emplace_back(i);
            }
            solve(x1,y1,mid-1,y2,v1),solve(mid+1,y1,x2,y2,v2);
        }else{
            int mid=y1 + y2 >> 1;
            for(int i=x1;i<=x2;++i){
                run(i,mid,x1,y1,x2,y2);
                for(Q*i:v)down(i->ans,dis[i->a]+dis[i->b]);
            }
            std::vector<Q*> v1,v2;
            for(Q*&i:v){
                if(max(i->a.y,i->b.y) < mid)v1.emplace_back(i);
                if(min(i->a.y,i->b.y) > mid)v2.emplace_back(i);
            }
            solve(x1,y1,x2,mid-1,v1),solve(x1,mid+1,x2,y2,v2);
        }
    }
    char buf[(int)3e7],*vin=buf-1;
    char bufo[(int)3e7],*vout=bufo-1;
    inline void pc(int x){*++vout=x;}
    inline void put(int x){if(x>9)put(x/10);pc(x%10+48);}
    #define getchar() (*++vin)
    int x,ch;
    inline int read(){
        while(isspace(ch=getchar()));x=ch&15;
        while(isdigit(ch=getchar()))x=x*10+(ch&15);
        return x;
    }
    int main(){
        fread(buf,1,sizeof buf,stdin);
        n=read(),m=read();
        for(int i=1;i<=n;++i)
            for(int j=1;j<m;++j){
                adde({i,j},{i,j+1},read());
            }
        for(int i=1;i<n;++i)
            for(int j=1;j<=m;++j){
                adde({i,j},{i+1,j},read());
            }
        int q=read();;
        std::vector<Q*> v;
        for(int i=1;i<=q;++i)
            b[i].a.x=read(),b[i].a.y=read(),b[i].b.x=read(),b[i].b.y=read(),b[i].ans=2e9,v.push_back(b+i);
        solve(1,1,n,m,v);
        for(int i=1;i<=q;++i)
            put(b[i].ans),pc(10);
        fwrite(bufo,1,vout-bufo+1,stdout);
    }
  • 相关阅读:
    【springboot】处理【跨域】请求
    【JPA】【概念】JPA概念解析:CascadeType(各种级联操作)详解
    【JPA】关于SpringBoot使用JPA的更新操作(save方法和原生SQL方法)
    jpa @query上使用if判断
    【Jpa】动态多表if多条件联合查询,并对查询结果进行分页
    phpstorm2020.1 免注册
    uniapp实现多语言切换
    vue进页面input自动获取焦点
    vue-cli4使用less全局变量
    用js实现隐藏手机号中间四位
  • 原文地址:https://www.cnblogs.com/skip1978/p/10340982.html
Copyright © 2011-2022 走看看