印尼首都雅加達市有 NN 座摩天樓,它們排列成一條直線,咱們從左到右依次將它們編號爲 00 到 N−1N−1。除了這 NN 座摩天樓外,雅加達市沒有其餘摩天樓。node
有 MM 只叫作 「doge」 的神祕生物在雅加達市居住,它們的編號依次是 00 到 M−1M−1。編號爲 ii 的 doge 最初居住於編號爲 BiBi 的摩天樓。每隻 doge 都有一種神祕的力量,使它們可以在摩天樓之間跳躍,編號爲 ii 的 doge 的跳躍能力爲 PiPi (Pi>0Pi>0)。ios
在一次跳躍中,位於摩天樓 bb 而跳躍能力爲 pp 的 doge 能夠跳躍到編號爲 b−pb−p (若是 0≤b−p<N0≤b−p<N)或 b+pb+p (若是 0≤b+p<N0≤b+p<N)的摩天樓。atom
編號爲 00 的 doge 是全部 doge 的首領,它有一條緊急的消息要儘快傳送給編 號爲 11 的 doge。任何一個收到消息的 doge 有如下兩個選擇:spa
請幫助 doge 們計算將消息從 00 號 doge 傳遞到 11 號 doge 所須要的最少總跳躍步數,或者告訴它們消息永遠不可能傳遞到 11 號 doge。code
輸入的第一行包含兩個整數 NN 和 MM。xml
接下來 MM 行,每行包含兩個整數 BiBi 和 PiPi。blog
輸出一行,表示所須要的最少步數。若是消息永遠沒法傳遞到 11 號 doge,輸出 −1−1。input
5 3 0 2 1 1 4 1
5
下面是一種步數爲 55 的解決方案:string
全部數據都保證 0≤Bi<N0≤Bi<N。io
時間限制:1s1s
空間限制:256MB
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #define maxn 30010 using namespace std; int B,num,tot,s,t,head[maxn*110],m,n,vis[maxn*110],d[maxn*110],pos[110][maxn]; struct node{int b,p;}a[maxn]; struct Node{int to,pre,v;}e[maxn*500]; void Insert(int from,int to,int v){ e[++num].to=to; e[num].v=v; e[num].pre=head[from]; head[from]=num; } queue<int>q; void spfa(){ for(int i=0;i<=tot;i++)d[i]=1e9,vis[i]=0; q.push(a[0].b); d[a[0].b]=0;vis[a[0].b]=1; while(!q.empty()){ int x=q.front();q.pop();vis[x]=0; for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if(d[to]>d[x]+e[i].v){ d[to]=d[x]+e[i].v; if(!vis[to])q.push(to),vis[to]=1; } } } } int main(){ scanf("%d%d",&n,&m); for(int i=0;i<m;i++)scanf("%d%d",&a[i].b,&a[i].p); tot=n-1; B=min(100,(int)sqrt(n)); for(int i=1;i<=B;i++) for(int j=0;j<i;j++) for(int k=j;k<n;k+=i){ pos[i][k]=++tot; Insert(tot,k,0); if(k>=i){ Insert(tot,tot-1,1); Insert(tot-1,tot,1); } } for(int i=0;i<m;i++){ if(a[i].p<=B) Insert(a[i].b,pos[a[i].p][a[i].b],0); else { for(int j=1;;j++) if(j*a[i].p+a[i].b>=n)break; else Insert(a[i].b,j*a[i].p+a[i].b,j); for(int j=1;;j++) if(a[i].b-j*a[i].p<0)break; else Insert(a[i].b,a[i].b-j*a[i].p,j); } } spfa(); if(d[a[1].b]==1e9)puts("-1"); else printf("%d\n",d[a[1].b]); return 0; }