zoukankan      html  css  js  c++  java
  • BZOJ 4070: [Apio2015]雅加达的摩天楼

    Descrption

    有(m)只doge,每只doge只能到(b_i+kp_i,kin Z),求0号doge将信息传给1号doge的最少跳跃步数.(nleqslant 3 imes 10^4)

    Solution

    分块.

    将(p)分成大于(sqrt n)和小于等于(sqrt n)的两部分,然后小于的部分可以暴力建好图再连边,大于的部分直接连所有能到达的位置即可。

    复杂度(O(nsqrt n)).

    PS:UOJ上过不了Extra Text...

    其实时间复杂度没问题...就是有点卡内存...

    Code

    /**************************************************************
        Problem: 4070
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:8152 ms
        Memory:175408 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    #define uor(i,j,k) for(int i=j;i<=(int)k;i++)
    #define uep(i,j,k) for(int i=j;i<(int)k;i++)
     
    inline int in(int x=0,char s=getchar()) { while(s>'9'||s<'0')s=getchar();
        while(s>='0'&&s<='9')x=x*10+s-'0',s=getchar();return x; }
     
    const int N = 30001;
    const int B = 86;
    const int NN = N*B+N;
    const int M = N*B*5;
    const int oo = 0x3f3f3f3f;
     
    int n,m,ss,tt,pe;
    int to[M],ww[M];
    int nxt[M],hd[NN];
    int d[NN];
    bool b[NN];
     
    int get_id(int x,int y) { return x*n+y; }
    void AddEdge(int u,int v,int w) 
    { nxt[++pe]=hd[u],to[pe]=v,ww[pe]=w,hd[u]=pe; }
     
    int SPFA(int s,int t) {
        memset(d,0x3f,sizeof(d));
        queue<int> q;q.push(s);
        d[s]=0,b[s]=1;
        for(int x;!q.empty();) {
            x=q.front(),q.pop(),b[x]=0;
            for(int i=hd[x];i;i=nxt[i]) {
                int v=to[i],w=ww[i];
                if(d[x]+w<d[v]) {
                    d[v]=d[x]+w;
                    if(!b[v]) q.push(v),b[v]=1;
                }
            }
        }return d[t]==oo?-1:d[t];
    }
    /*
    void out() {
        for(int i=0;i<=(B+1)*n+n-1;i++) {
            cout<<i<<"-->";
            uep(j,0,g[i].size()) cout<<edge[g[i][j]].to<<" ";
            cout<<endl;
        }
    }*/
    int main() {
    //  cout<<sizeof(to)*4/1024.0/1024.0<<endl;
        n=in(),m=in();
        uep(i,0,m) {
            int b=in(),p=in();
            if(i==0) ss=b;
            if(i==1) tt=b;
            if(p>B) {
                for(int j=1;j*p<n;j++) {
                    if(b+j*p<n) AddEdge(b,b+j*p,j);
                    if(b-j*p>=0) AddEdge(b,b-j*p,j);
                }
            } else {
                AddEdge(b,get_id(p,b),0);
            }
        }
        for(int i=1;i<=B;i++) for(int j=0;j<i;j++) for(int k=j+i;k<n;k+=i)
            AddEdge(get_id(i,k),get_id(i,k-i),1),AddEdge(get_id(i,k-i),get_id(i,k),1);
        for(int i=1;i<=B;i++) for(int j=0;j<i;j++) for(int k=j;k<n;k+=i)
            AddEdge(get_id(i,k),k,0);
         
    //  out();
         
        printf("%d
    ",SPFA(ss,tt));
        return 0;
    }
    

      

  • 相关阅读:
    element-ui 中Message 消息提示
    MYSQL 常用语法格式
    python 爬取必应每日图片
    linux:文件权限管理
    如何建立自我学习的"触发机制"?
    总有那么一些人,把自己的思想强加给别人
    linux 控制history命令历史记录
    linux apt-get 安装与卸载命令
    ubuntu16.04下 安装java8
    历史与过去是一面镜子,它照到的是你现在的自己
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6803985.html
Copyright © 2011-2022 走看看