• bzoj4456 [Zjoi2016]旅行者


    Description

    小Y来到了一个新的城市旅行。她发现了这个城市的布局是网格状的,也就是有n条从东到西的道路和m条从南到北的道路,这些道路两两相交形成n×m个路口 (i,j)(1≤i≤n,1≤j≤m)。她发现不同的道路路况不同,所以通过不同的路口需要不同的时间。通过调查发现,从路口(i,j)到路口(i,j+1)需要时间 r(i,j),从路口(i,j)到路口(i+1,j)需要时间c(i,j)。注意这里的道路是双向的。小Y有q个询问,她想知道从路口(x1,y1)到路口(x2,y2)最少需要花多少时间。 

    Input

    第一行包含 2 个正整数n,m,表示城市的大小。
    接下来n行,每行包含m-1个整数,第i行第j个正整数表示从一个路口到另一个路口的时间r(i,j)。
    接下来n-1行,每行包含m个整数,第i行第j个正整数表示从一个路口到另一个路口的时间c(i,j)。
    接下来一行,包含1个正整数q,表示小Y的询问个数。
    接下来q行,每行包含4个正整数 x1,y1,x2,y2,表示两个路口的位置。

    Output

    输出共q行,每行包含一个整数表示从一个路口到另一个路口最少需要花的时间。

    Sample Input

    2 2
    2
    3
    6 4
    2
    1 1 2 2
    1 2 2 1

    Sample Output

    6
    7

    HINT

    正解:分治+$dijkstra$。

    这道题的思路很神奇啊。。

    直接暴力搞肯定炸,我们考虑分治。

    这相当于平面上的分治,我们每次在横轴和纵轴中选择较长的那一条二分,二分出一条中轴,然后分别以中轴上每个点为起点,在当前这个矩形内跑最短路,并更新每个询问。递归分治时我们就把完全在左边的路径放到左边,完全在右边的路径放在右边。如果一条路径跨越了中轴线,那么它肯定已经求出最短路,就不用再递归了。

    为了降低复杂度,我们使用手写堆,因为手写堆可以让每个结点只加入一次,$dijkstra$的复杂度就可以降低。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <queue>
     10 #include <stack>
     11 #include <map>
     12 #include <set>
     13 #define inf ((1<<30)-1)
     14 #define N (500010)
     15 #define il inline
     16 #define RG register
     17 #define ll long long
     18 #define pos(i,j) ((i-1)*m+j)
     19 
     20 using namespace std;
     21 
     22 int head[N],dis[N],ans[N],bl[N][2],n,m,num,qq;
     23 
     24 struct node{ int i,lx,ly,rx,ry; }q[N],qu[N];
     25 struct edge{ int nt,to,dis; }g[N];
     26 struct heap{
     27 
     28 #define fa (x>>1)
     29 #define ls (x<<1)
     30 #define rs (x<<1|1)
     31     
     32     int a[N],id[N],len;
     33 
     34     il void push(RG int u){
     35     if (!id[u]) id[u]=++len,a[len]=u; RG int x=id[u];
     36     while (fa){
     37         if (dis[a[x]]>=dis[a[fa]]) break;
     38         swap(a[x],a[fa]),id[a[x]]=x,id[a[fa]]=fa,x=fa;
     39     }
     40     return;
     41     }
     42     
     43     il void pop(){
     44     id[a[1]]=0,a[1]=a[len--]; if (len) id[a[1]]=1; RG int x=1,son;
     45     while (ls<=len){
     46         son=(rs<=len && dis[a[rs]]<dis[a[ls]]) ? rs : ls;
     47         if (dis[a[x]]<=dis[a[son]]) break;
     48         swap(a[x],a[son]),id[a[x]]=x,id[a[son]]=son,x=son;
     49     }
     50     return;
     51     }
     52     
     53 #undef fa
     54 #undef ls
     55 #undef rs
     56     
     57 }Q;
     58 
     59 il int gi(){
     60     RG int x=0,q=1; RG char ch=getchar();
     61     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     62     if (ch=='-') q=-1,ch=getchar();
     63     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     64     return q*x;
     65 }
     66 
     67 il void insert(RG int from,RG int to,RG int dis){
     68     g[++num]=(edge){head[from],to,dis},head[from]=num; return;
     69 }
     70 
     71 il void dijkstra(RG int lx,RG int rx,RG int ly,RG int ry,RG int inix,RG int iniy){
     72     for (RG int i=lx;i<=rx;++i)
     73     for (RG int j=ly;j<=ry;++j) dis[pos(i,j)]=inf;
     74     dis[pos(inix,iniy)]=0,Q.push(pos(inix,iniy));
     75     while (Q.len){
     76     RG int x=Q.a[1],v,nowx,nowy; Q.pop();
     77     for (RG int i=head[x];i;i=g[i].nt){
     78         v=g[i].to,nowx=bl[v][0],nowy=bl[v][1];
     79         if (nowx<lx || nowx>rx || nowy<ly || nowy>ry) continue;
     80         if (dis[v]>dis[x]+g[i].dis) dis[v]=dis[x]+g[i].dis,Q.push(v);
     81     }
     82     }
     83     return;
     84 }
     85 
     86 il void solve(RG int lx,RG int rx,RG int ly,RG int ry,RG int l,RG int r){
     87     if (lx>rx || ly>ry || l>r) return;
     88     if (l==r){
     89     dijkstra(lx,rx,ly,ry,q[l].lx,q[l].ly);
     90     ans[q[l].i]=min(ans[q[l].i],dis[pos(q[l].rx,q[l].ry)]);
     91     return;
     92     }
     93     RG int mid,t1=l-1,t2=r+1;
     94     if (rx-lx>=ry-ly){
     95     mid=(lx+rx)>>1;
     96     for (RG int y=ly;y<=ry;++y){
     97         dijkstra(lx,rx,ly,ry,mid,y);
     98         for (RG int i=l;i<=r;++i)
     99         ans[q[i].i]=min(ans[q[i].i],dis[pos(q[i].lx,q[i].ly)]+dis[pos(q[i].rx,q[i].ry)]);
    100     }
    101     for (RG int i=l;i<=r;++i)
    102         if (q[i].lx<mid && q[i].rx<mid) qu[++t1]=q[i];
    103         else if (q[i].lx>mid && q[i].rx>mid) qu[--t2]=q[i];
    104     for (RG int i=l;i<=t1;++i) q[i]=qu[i];
    105     for (RG int i=r;i>=t2;--i) q[i]=qu[i];
    106     solve(lx,mid,ly,ry,l,t1),solve(mid+1,rx,ly,ry,t2,r);
    107     } else{
    108     mid=(ly+ry)>>1;
    109     for (RG int x=lx;x<=rx;++x){
    110         dijkstra(lx,rx,ly,ry,x,mid);
    111         for (RG int i=l;i<=r;++i)
    112         ans[q[i].i]=min(ans[q[i].i],dis[pos(q[i].lx,q[i].ly)]+dis[pos(q[i].rx,q[i].ry)]);
    113     }
    114     for (RG int i=l;i<=r;++i)
    115         if (q[i].ly<mid && q[i].ry<mid) qu[++t1]=q[i];
    116         else if (q[i].ly>mid && q[i].ry>mid) qu[--t2]=q[i];
    117     for (RG int i=l;i<=t1;++i) q[i]=qu[i];
    118     for (RG int i=r;i>=t2;--i) q[i]=qu[i];
    119     solve(lx,rx,ly,mid,l,t1),solve(lx,rx,mid+1,ry,t2,r);
    120     }
    121     return;
    122 }
    123 
    124 int main(){
    125 #ifndef ONLINE_JUDGE
    126     freopen("tourist.in","r",stdin);
    127     freopen("tourist.out","w",stdout);
    128 #endif
    129     n=gi(),m=gi();
    130     for (RG int i=1;i<=n*m;++i) bl[i][0]=(i-1)/m+1,bl[i][1]=(i-1)%m+1;
    131     for (RG int i=1;i<=n;++i)
    132     for (RG int j=1,w;j<m;++j)
    133         w=gi(),insert(pos(i,j),pos(i,j+1),w),insert(pos(i,j+1),pos(i,j),w);
    134     for (RG int i=1;i<n;++i)
    135     for (RG int j=1,w;j<=m;++j)
    136         w=gi(),insert(pos(i,j),pos(i+1,j),w),insert(pos(i+1,j),pos(i,j),w);
    137     qq=gi();
    138     for (RG int i=1;i<=qq;++i)
    139     q[i].i=i,q[i].lx=gi(),q[i].ly=gi(),q[i].rx=gi(),q[i].ry=gi(),ans[i]=inf<<1;
    140     solve(1,n,1,m,1,qq); for (RG int i=1;i<=qq;++i) printf("%d
    ",ans[i]);
    141     return 0;
    142 }
  • 相关阅读:
    开发中的一些总结。。。
    Directory Listing Denied错误
    webservice的一些使用心得。。
    vs2005 sp1 补丁后,不能初始化
    谈C/C++指针精髓
    CString 的函数
    javaScript 中 call 函数的用法说明 & 继承
    条款12: 尽量使用初始化而不要在构造函数里赋值(effectiveC++)
    js日期时间函数(经典+完善+实用)
    学习之路一 记录学习中的手记
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7231160.html
Copyright © 2020-2023  润新知