此题卡Dijkstra...
Code:
#include <bits/stdc++.h>
#define N 30005
#define M 4000000
#define ll long long
#define inf 100000000
#define E 14300000
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll d[M];
int n,m,block,cnt,edges,s,t;
int id[N][103],hd[M],to[E],nex[E],val[E],done[M];
struct Node
{
int u;
ll dis;
Node(int u=0,ll dis=0):u(u),dis(dis){}
bool operator<(Node b) const
{
return b.dis<dis;
}
};
priority_queue<Node>q;
void add(int u,int v,int c)
{
// ++edges;
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;
}
void Dijkstra()
{
memset(d,0x3f,sizeof(d));
for(d[s]=0,q.push(Node(s,0));!q.empty();)
{
Node e=q.top(); q.pop();
int u=e.u;
if(done[u]) continue;
done[u]=1;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(d[v]>d[u]+val[i])
{
d[v]=d[u]+val[i];
q.push(Node(v, d[v]));
}
}
}
}
int main()
{
int i,j,k;
// setIO("input");
scanf("%d%d",&n,&m);
block=min(100,(int)sqrt(n));
cnt = n + 23;
for(i=1;i<=block;++i)
{
for(j=0;j<i;++j)
{
for(k=j;k<n;k+=i)
{
id[k][i]=++cnt;
add(cnt,k,0);
if(k>=i)
add(cnt-1,cnt,1), add(cnt,cnt-1,1);
}
}
}
for(i=1;i<=m;++i)
{
int a,b;
scanf("%d%d",&a,&b);
if(i==1) s=a;
if(i==2) t=a;
if(b<=block)
add(a, id[a][b], 0);
else
{
int tt=0;
for(j=a-b;j>=0;j-=b) add(a,j,++tt);
tt=0;
for(j=a+b;j<n;j+=b) add(a,j,++tt);
}
}
// printf("%d %d\n",cnt,edges);
Dijkstra();
printf("%lld\n",d[t]>=inf?-1:d[t]);
return 0;
}