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

    Description

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

     
    有 M 只叫做 “doge” 的神秘生物在雅加达市居住,它们的编号依次是 0 到 M−1。编号为 i 的 doge 最初居住于编号为 Bi 的摩天楼。每只 doge 都有一种神秘的力量,使它们能够在摩天楼之间跳跃,编号为 i 的 doge 的跳跃能力为 Pi (Pi>0)。
     
    在一次跳跃中,位于摩天楼 b 而跳跃能力为 p 的 doge 可以跳跃到编号为 b−p (如果 0≤b−p<N)或 b+p (如果 0≤b+p<N)的摩天楼。
     
    编号为 0 的 doge 是所有 doge 的首领,它有一条紧急的消息要尽快传送给编 号为 1 的 doge。任何一个收到消息的 doge 有以下两个选择:
     
    跳跃到其他摩天楼上;
    将消息传递给它当前所在的摩天楼上的其他 doge。
    请帮助 doge 们计算将消息从 0 号 doge 传递到 1 号 doge 所需要的最少总跳跃步数,或者告诉它们消息永远不可能传递到 1 号 doge。
     

    Input

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

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

    Output

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

     

    Sample Input

    5 3
    0 2
    1 1
    4 1

    Sample Output

    5
    explanation
    下面是一种步数为 5 的解决方案:
    0 号 doge 跳跃到 2 号摩天楼,再跳跃到 4 号摩天楼(2 步)。
    0 号 doge 将消息传递给 2 号 doge。
    2 号 doge 跳跃到 3 号摩天楼,接着跳跃到 2 号摩天楼,再跳跃到 1 号摩天楼(3 步)。
    2 号 doge 将消息传递给 1 号 doge。

    HINT

     子任务


    所有数据都保证 0≤Bi<N。

     

    子任务 1 (10 分)

    1≤N≤10

    1≤Pi≤10

    2≤M≤3

    子任务 2 (12 分)

    1≤N≤100

    1≤Pi≤100

    2≤M≤2000

    子任务 3 (14 分)

    1≤N≤2000

    1≤Pi≤2000

    2≤M≤2000

    子任务 4 (21 分)

    1≤N≤2000

    1≤Pi≤2000

    2≤M≤30000

    子任务 5 (43 分)

    1≤N≤30000

    1≤Pi≤30000

    2≤M≤30000
    题解:
    http://blog.csdn.net/regina8023/article/details/45766241
    code:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 char ch;
     8 bool ok;
     9 void read(int &x){
    10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    11     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    12     if (ok) x=-x;
    13 }
    14 const int maxn=30000*125;
    15 const int maxm=maxn*5;
    16 const int inf=1061109567;
    17 int n,m,a,b,lim;
    18 struct Graph{
    19     int tot,now[maxn],son[maxm],pre[maxm],val[maxm];
    20     int head,tail,que[maxn],dis[maxn];
    21     bool bo[maxn];
    22     void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
    23     int spfa(){
    24         memset(dis,63,sizeof(dis));
    25         head=0,tail=1,que[1]=0,bo[0]=0,dis[0]=0;
    26         while (head!=tail){
    27             if (++head==maxn) head=1;
    28             int u=que[head];
    29             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    30                 if (dis[v]>dis[u]+val[p]){
    31                     dis[v]=dis[u]+val[p];
    32                     if (!bo[v]){
    33                         if (++tail==maxn) tail=1;
    34                         que[tail]=v,bo[v]=1;
    35                     }
    36                 }
    37             bo[u]=0;
    38         }
    39         if (dis[1]==inf) dis[1]=-1;
    40         return dis[1];
    41     }
    42 }G;
    43 int f(int x,int y){return m+x*n+y;}
    44 int main(){
    45     read(n),read(m),lim=sqrt(m/2);
    46     for (int t=1;t<=lim;t++) for (int i=0;i<n;i++) G.put(f(t,i),f(0,i),0);
    47     for (int t=1;t<=lim;t++) for (int i=t;i<n;i++) G.put(f(t,i-t),f(t,i),1),G.put(f(t,i),f(t,i-t),1);
    48     for (int i=0;i<m;i++){
    49         read(a),read(b);
    50         G.put(i,f(0,a),0),G.put(f(0,a),i,0);
    51         if (b<=lim) G.put(i,f(b,a),0);
    52         else{
    53             for (int j=1;a+b*j<n;j++) G.put(i,f(0,a+b*j),j);
    54             for (int j=1;a-b*j>=0;j++) G.put(i,f(0,a-b*j),j);
    55         }
    56     }
    57     printf("%d
    ",G.spfa());
    58     return 0;
    59 }
  • 相关阅读:
    Linux之网络基础
    Tomcat配置虚拟目录并发布web应用
    Linux之权限管理操作
    Linux之shell编程基础
    Python简介
    Python代码注释 Python零基础入门教程
    Python Pycharm Anacanda 区别
    Python Hello World入门
    Python2.x 和 Python3.x,如何选择?
    数据库课程设计心得【1】
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5431398.html
Copyright © 2011-2022 走看看