zoukankan      html  css  js  c++  java
  • 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
    ",cnt,edges);            
        Dijkstra(); 
        printf("%lld
    ",d[t]>=inf?-1:d[t]);   
        return 0;  
    }
    

      

  • 相关阅读:
    Java(二)
    JS === 关于getElementsByClassName()
    JS === 简易放大镜
    JS === 拖拽盒子
    JS === 实现多个光标跟随事件
    JS === 实现回到顶部
    JS === 实现通过点击td 跳转相应的图片
    final、static关键字
    java面向对象——构造方法
    java面向对象——多态
  • 原文地址:https://www.cnblogs.com/guangheli/p/11547462.html
Copyright © 2011-2022 走看看