[BZOJ 4070] [Apio2015] the skyscraper in Jakarta, bzojapio2015
4070: [Apio2015] skyscraper in Jakarta
Time limit: 1000 MS
Memory limit: 262144 KB
Description
The city of Jakarta has N skyscrapers located on a line, conveniently numbered 0 through N-1 from left to right. There are no other skyscrapers in Jakarta.
Jakarta is inhabited by M mystical creatures called "doge" s. the doges are conveniently numbered 0 through M-1. doge I initially resides in skyscraper Bi. doge I has a mystical power, represented with a positive integer Pi. this mystical power enables doges to jump between skyscrapers. in a single jump, a doge with superpower p that is currently in skyscraper B can move to either skyscraper B + p (if 0 ≤ B + p <N) or skyscraper B-p (if 0 ≤ B-p <N ).
Doge 0 is the most awesome doge, and it is the leader of all the doges. it has an urgent news for doge 1, and wants the news to reach doge 1 as quickly as possible. any doge that has ed the news can do any of the following actions:
Make a jump to move to some other skyscraper.
Pass the news to another doge in the same skyscraper.
Please help the doges by calculating the minimum number of total jumps required by all doges to pass the news to doge 1, or if it is impossible to do so.
Input Format
The first line contains two integers N and M. Each of the next M lines contains two integers Bi and Pi.
Output Format
A single line containing the minimum number of total jumps, or-1 if it is impossible.
Sample Input
5 3
0 2
1 1
4 1
Sample Output
5
Explanation
Here is one of the possible scenarios to pass the news using 5 jumps:
Doge 0 jumps to skyscraper 2 and then to skyscraper 4 (2 jumps ).
Doge 0 passes the news to doge 2.
Doge 2 jumps to skyscraper 3, and then to skyscraper 2, and then to skyscraper 1 (3 jumps ).
Doge 2 passes the news to doge 1.
Subtasks
For each subtask,
0 ≤ Bi <N
Subtask 1 (10 points)
1 ≤ N ≤ 10
1 ≤ Pi ≤ 10
2 ≤ M ≤ 3
Subtask 2 (12 points)
1 ≤ N ≤100
1 ≤ Pi ≤100
2 ≤ M ≤ 2,000
Subtask 3 (14 points)
1 ≤ N ≤2,000
1 ≤ Pi ≤2,000
2 ≤ M ≤ 2,000
Subtask 4 (21 points)
1 ≤ N ≤2,000
1 ≤ Pi ≤2,000
2 ≤ M ≤ 30,000
Subtask 5 (43 points)
1 ≤ N ≤30,000
1 ≤ Pi ≤30,000
2 ≤ M ≤ 30,000
Block + short circuit.
If you run the short circuit directly, the worst problem may occur. N2 Side.
Consider the following parts:
① Pi> n has been √
It can be done directly with brute force, because at most Nn commandid √ Side
② Pi ≤ n 00000000√
From each point, only N rows 0000√ Method, so there are only Nn commandid √ Side.
We can add some auxiliary points to implement preprocessing:
Enumerate this ≤N limit 0000√ Length. N Secondary point, connecting the forward to the corresponding position, while the direction can come from and arrive at the secondary point.
You can simply read the secondary point that is directly connected to him.
(For details, refer to the Code)
#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <cstdlib>#include <queue>#include <vector>#define M 30005#define pb push_back#define LL long longusing namespace std;queue<int> q;int B,tot=0,cnt,s,t,h[M*110],m,n,inq[M*110];int d[M*110],pos[105][M];struct data{ int b,p;}a[M];struct edge{ int y,ne,v;}e[M*500];void Addedge(int x,int y,int v){ e[++tot].y=y; e[tot].v=v; e[tot].ne=h[x]; h[x]=tot;}void SPFA(){ for (int i=0;i<=cnt;i++) d[i]=1e9,inq[i]=0; q.push(a[0].b); d[a[0].b]=0,inq[a[0].b]=1; while (!q.empty()) { int x=q.front(); q.pop(); inq[x]=0; for (int i=h[x];i;i=e[i].ne) { int y=e[i].y; if (d[y]>d[x]+e[i].v) { d[y]=d[x]+e[i].v; if (!inq[y]) q.push(y),inq[y]=1; } } }}int main(){ scanf("%d%d",&n,&m); for (int i=0;i<m;i++) scanf("%d%d",&a[i].b,&a[i].p); cnt=n-1; B=min((int)sqrt(n),100); 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]=++cnt; Addedge(cnt,k,0); if (k>=i) { Addedge(cnt,cnt-1,1); Addedge(cnt-1,cnt,1); } } for (int i=0;i<m;i++) { if (a[i].p<=B) Addedge(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 Addedge(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 Addedge(a[i].b,a[i].b-j*a[i].p,j); } } SPFA(); if (d[a[1].b]==1e9) cout<<-1<<endl; else cout<<d[a[1].b]<<endl; return 0;}