BZOJ 4070: [Apio2015]雅加达的摩天楼 根号分治+spfa

时间:2019-09-19
本文章向大家介绍BZOJ 4070: [Apio2015]雅加达的摩天楼 根号分治+spfa,主要包括BZOJ 4070: [Apio2015]雅加达的摩天楼 根号分治+spfa使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

此题卡Dijkstra...

Code: 

#include <bits/stdc++.h>  
#define N 30005   
#define M 4000000
#define ll long long  
#define inf 100000000
#define E 14300000
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;      
ll d[M];   
int n,m,block,cnt,edges,s,t;          
int id[N][103],hd[M],to[E],nex[E],val[E],done[M];       
struct Node 
{
    int u; 
    ll dis; 
    Node(int u=0,ll dis=0):u(u),dis(dis){}    
    bool operator<(Node b) const
    {
        return b.dis<dis;         
    }
};   
priority_queue<Node>q;   
void add(int u,int v,int c) 
{
    // ++edges;         
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;   
} 
void Dijkstra() 
{  
    memset(d,0x3f,sizeof(d)); 
    for(d[s]=0,q.push(Node(s,0));!q.empty();) 
    {
        Node e=q.top(); q.pop(); 
        int u=e.u;  
        if(done[u]) continue;  
        done[u]=1; 
        for(int i=hd[u];i;i=nex[i]) 
        {
            int v=to[i]; 
            if(d[v]>d[u]+val[i]) 
            {
                d[v]=d[u]+val[i]; 
                q.push(Node(v, d[v]));   
            }
        }
    }   
}
int main() 
{  
    int i,j,k;  
    // setIO("input"); 
    scanf("%d%d",&n,&m); 
    block=min(100,(int)sqrt(n));        
    cnt = n + 23;     
    for(i=1;i<=block;++i)        
    {
        for(j=0;j<i;++j)               
        {
            for(k=j;k<n;k+=i)          
            {
                id[k][i]=++cnt;   
                add(cnt,k,0);      
                if(k>=i)    
                    add(cnt-1,cnt,1), add(cnt,cnt-1,1);    
            }
        }
    }
    for(i=1;i<=m;++i)  
    {
        int a,b; 
        scanf("%d%d",&a,&b);    
        if(i==1) s=a;        
        if(i==2) t=a;   
        if(b<=block) 
            add(a, id[a][b], 0);    
        else 
        {
            int tt=0; 
            for(j=a-b;j>=0;j-=b) add(a,j,++tt);        
            tt=0; 
            for(j=a+b;j<n;j+=b) add(a,j,++tt);     
        }
    }  
    // printf("%d %d\n",cnt,edges);            
    Dijkstra(); 
    printf("%lld\n",d[t]>=inf?-1:d[t]);   
    return 0;  
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11547462.html