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

    印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1。除了这 N 座摩天楼外,雅加达市没有其他摩天楼。

    有 MM 只叫做 “战舰狗” 的神秘生物在雅加达市居住,它们的编号依次是 0 到 M−1。编号为 i 的 战舰狗 最初居住于编号为 Bi 的摩天楼。每只 战舰狗 都有一种神秘的力量,使它们能够在摩天楼之间跳跃,编号为 i 的 战舰狗 的跳跃能力为 Pi (Pi>0Pi>0)。

    在一次跳跃中,位于摩天楼 b 而跳跃能力为 p 的 战舰狗 可以跳跃到编号为 b−pb−p (如果 0≤b-p<N)或 b+p (如果 0≤b+p<N)的摩天楼。

    编号为 0 的 战舰狗 是所有 战舰狗 的首领,它有一条紧急的消息要尽快传送给编号为 1 的 战舰狗。任何一个收到消息的 战舰狗 有以下两个选择:

    跳跃到其他摩天楼上;
    将消息传递给它当前所在的摩天楼上的其他 战舰狗。
    请帮助 战舰狗 们计算将消息从 0 号 战舰狗 传递到 1 号 战舰狗 所需要的最少总跳跃步数,或者告诉它们消息永远不可能传递到 1 号 战舰狗。

    输入格式
    输入的第一行包含两个整数 N 和 M。

    接下来 MM 行,每行包含两个整数 Bi 和 Pi。

    输出格式
    输出一行,表示所需要的最少步数。如果消息永远无法传递到 1 号 战舰狗,输出 −1。

    思路{

      对于一条楼上的每一条狗.最直观的方法是把一个点拆成N条狗的点,然后最短路即可。
      然而炸空间我也是醉了。
      因此我们要用到一个调调的分块优化。
      应当是每个点的连通状态。意会一下。
      把一座楼分成1-块长层,那对于任意相同层数的狗可以在高空乱JB走。
      但连通长度p>块长的呢?------直接连边就可以了。
      然后YY一下,处理每条狗的激活关系。SPFA就可以了。
    }

     

    #include<bits/stdc++.h>
    #define RG register
    #define il inline 
    #define N 5500000
    #define Inf 2
    #define U unsigned short
    #define pos(i,j) (i*n+j)
    using namespace std;
    struct ed{int nxt,to,c;}e[30005*500];
    int head[30005*105],dis[30005*105],n,m,q,b,s,t;bool in[30005*105];int tot;
    void add(int u,int v,int c){e[tot].nxt=head[u];e[tot].to=v;e[tot].c=c;head[u]=tot++;}
    void ADD(int u,int v,int c){add(u,v,c),add(v,u,c);}
    void spfa(){
      queue<int>que;memset(dis,Inf,sizeof(dis));int SS=dis[t];
      que.push(s),in[s]=true,dis[s]=0;
      while(!que.empty()){
        int u=que.front();que.pop();in[u]=false;
        for(int i=head[u];i!=-1;i=e[i].nxt)if(dis[e[i].to]>dis[u]+e[i].c){
    	int v=e[i].to;dis[v]=dis[u]+e[i].c;
    	if(!in[v])que.push(v),in[v]=true;
          }
      }if(dis[t]==SS)cout<<"-1";
      else cout<<dis[t];
    }
    int main(){
      freopen("skyscraper.in","r",stdin);
      freopen("skyscraper.out","w",stdout);
      memset(head,-1,sizeof(head));
      cin>>n>>m;U int len=min((int)sqrt(n),100);
      for(RG int i=1;i<=len;++i)for(int j=1;j<=n;++j)add(pos(i,j),j,0);
      for(RG int i=1;i<=len;++i)for(int j=1;j<=n-i;++j)ADD(pos(i,j),pos(i,j+i),1);
      for(RG int i=1;i<=m;++i){int b,p;
        cin>>b>>p;b++;
        if(i==1)s=b;if(i==2)t=b;
        if(p<=len)add(b,pos(p,b),0);
        else {
          for(int j=1;j*p+b<=n;++j)add(b,b+j*p,j);
          for(int j=1;b-j*p>0;++j)add(b,b-j*p,j);
        }
      }spfa();
      return 0;
    }
    

      

     

  • 相关阅读:
    ccmenu里的位置
    【luogu P3346】诸神眷顾的幻想乡(广义 SAM)
    Snow的追寻(线段树)(LCA)
    【bzoj 4303】数列 / T4(K-D tree)
    选课 / T3(组合数)(容斥)
    随机游走 / T1(期望)(树形DP)
    【luogu P3898】期望异或 / T3 / 大新闻(数位DP)(数学)
    【luogu P7295】Paint by Letters P(前缀和)(欧拉公式)(bfs)(对偶图)
    【luogu P7294】Minimum Cost Paths P(二分)(单调栈)(斜率)
    【luogu P7293】Sum of Distances P(线段树)(图论)
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7219234.html
Copyright © 2011-2022 走看看