• luogu3645 [Apio2015]雅加达的摩天大楼 (分块+dijkstra)


    我们是想跑最短路的

    我们有两种建图方式:

    1.对于每个doge i,连向B[j]==B[i]+P[i]*k ,k=..,-2,-1,0,1,2,... ,边权=|k|,这样连的复杂度是$O(Nsumlimits_{i=1}^{m}frac{1}{P[i]})$

    2.对于每个楼i,建max(P[i])个点,表示可以有一个doge经过这个楼来跳j个距离,也就是说,给P[i][j]连向P[i-j][j]和P[i+j][j],边权=1,而且还要给所有的P[i]连起来,边权是0.

    这样连的复杂度是$O(Nsumlimits_{i=1}^{m}P[i])$,其中P[i]是互不相同的(相同就不加了)

    然而都过不了

    然后我们发现,复杂度一个是乘P[i],一个是除以P[i],这就启发我们采用分块的思想,对于P[i]大于$sqrt{N}$的使用第1种建法,小于的使用第二种建法,整体的复杂度就变成$O(Nsqrt{N})$了

    然而因为玄学的常数问题,我们需要:

    1.让那个分块的边界取$min(sqrt{N},100)$(我也不知道为什么)

    2.在做最短路的时候再计算边,而不是提前都建好

    3.深吸一口氧气(必要)

    4.使用spfa而不是dijkstra(我也不知道为什么,但我还是用了dijkstra,然后就挂了...)

    (代码写一年还写得巨丑)

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define lowb(x) ((x)&(-(x)))
     4 #define REP(i,n0,n) for(i=n0;i<=n;i++)
     5 #define PER(i,n0,n) for(i=n;i>=n0;i--)
     6 #define MAX(a,b) ((a>b)?a:b)
     7 #define MIN(a,b) ((a<b)?a:b)
     8 #define CLR(a,x) memset(a,x,sizeof(a))
     9 #define rei register int
    10 using namespace std;
    11 typedef long long ll;
    12 const int maxn=30030,sqrtn=200;
    13 
    14 inline ll rd(){
    15     ll x=0;char c=getchar();int neg=1;
    16     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    17     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    18     return x*neg;
    19 }
    20 
    21 struct Node{
    22     int x,y,d;bool isp;
    23     Node (int a,int b,int c,bool s){x=a,y=b,d=c,isp=s;}
    24 }S=Node(0,0,0,0);
    25 int N,SN,M,B[maxn],P[maxn];
    26 int dis[maxn*sqrtn],poi[maxn][2],ph[maxn];
    27 bool flag[maxn*sqrtn];
    28 priority_queue<Node,vector<Node>,greater<Node> > q;
    29 
    30 bool operator > (Node a,Node b){return a.d>b.d;}
    31 inline int id(Node a){return a.isp?a.x:M+1+a.x+a.y*N;}
    32 inline void print(int x,Node a){printf("Node%d:%d %d %d %d
    ",x,a.x,a.y,a.d,a.isp);}
    33 
    34 inline int dijkstra(){
    35     memset(dis,127,sizeof(dis));
    36     dis[id(S)]=0;q.push(S);
    37     while(!q.empty()){
    38         Node p=q.top();q.pop();
    39         if(((!p.isp)&&p.x==B[1])||(p.isp&&p.x==1)) return p.d;
    40         if(flag[id(p)]) continue;
    41         
    42         if(!p.isp){
    43             for(int i=ph[p.x];i!=-1;i=poi[i][1]){
    44                 if(P[poi[i][0]]>SN){
    45                     if(dis[poi[i][0]]<=p.d) continue;
    46                     dis[poi[i][0]]=p.d;
    47                     q.push(Node(poi[i][0],0,p.d,1));
    48                 }else if(P[poi[i][0]]!=p.y){
    49                     Node x=Node(p.x,P[poi[i][0]],p.d,0);
    50                     if(dis[id(x)]<=p.d) continue;
    51                     dis[id(x)]=p.d;q.push(x);
    52                 }
    53             }
    54             if(p.y){
    55                 Node xx=Node(p.x+p.y,p.y,p.d+1,0);
    56                 if(p.x+p.y<N&&dis[id(xx)]>p.d+1){
    57                     dis[id(xx)]=p.d+1;
    58                     q.push(xx);
    59                 }xx.x=p.x-p.y;
    60                 if(p.x-p.y>=0&&dis[id(xx)]>p.d+1){
    61                     dis[id(xx)]=p.d+1;
    62                     q.push(xx);
    63                 }
    64             }
    65         }
    66         else{
    67             for(int i=B[p.x]+P[p.x],j=1;i<N;i+=P[p.x],j++){
    68                 Node a=Node(i,0,p.d+j,0);
    69                 if(dis[id(a)]>p.d+j){
    70                     dis[id(a)]=p.d+j;q.push(a);
    71                 }
    72             }
    73             for(int i=B[p.x]-P[p.x],j=1;i>=0;i-=P[p.x],j++){
    74                 Node a=Node(i,0,p.d+j,0);
    75                 if(dis[id(a)]>p.d+j){
    76                     dis[id(a)]=p.d+j;q.push(a);
    77                 }
    78             }
    79         }
    80         flag[id(p)]=1;
    81     }return -1;
    82 }
    83 
    84 int main(){
    85     //freopen(".in","r",stdin);
    86     rei i,j,k;
    87     N=rd(),M=rd();SN=min(100,(int)sqrt(N));
    88     memset(ph,-1,sizeof(ph));
    89     for(i=0;i<M;i++){
    90         B[i]=rd(),P[i]=rd();
    91         poi[i][0]=i;poi[i][1]=ph[B[i]];ph[B[i]]=i;
    92     }S=Node(B[0],0,0,0);
    93     printf("%d
    ",dijkstra());
    94     return 0;
    95 }
  • 相关阅读:
    2020年. NET Core面试题
    java Context namespace element 'component-scan' and its parser class ComponentScanBeanDefinitionParser are only available on JDK 1.5 and higher 解决方法
    vue 淡入淡出组件
    java http的get、post、post json参数的方法
    vue 父子组件通讯案例
    Vue 生产环境解决跨域问题
    npm run ERR! code ELIFECYCLE
    Android Studio 生成apk 出现 :error_prone_annotations.jar (com.google.errorprone:error) 错误
    记忆解析者芜青【总集】
    LwIP应用开发笔记之十:LwIP带操作系统基本移植
  • 原文地址:https://www.cnblogs.com/Ressed/p/9649006.html
Copyright © 2020-2023  润新知