题意
题解
边权为 1 1 1 的图, B F S BFS BFS 即可。考虑 d o g e doge doge 的状态,为位置与跳跃能力的二元组,用 ( b , p ) (b,p) (b,p) 表示。若跳跃能力为 p p p,则其可达位置数为 N / p N/p N/p。
考虑根号分治。若 p < N p<\sqrt N p<N,状态数至多为 O ( N N ) O(N\sqrt N) O(NN);若 p ≥ N p\geq \sqrt N p≥N,状态数至多为 O ( M N ) O(M\sqrt N) O(MN)。 S T L b i t s e t STL\ bitset STL bitset 记录状态, B F S BFS BFS 求解,总时间复杂度 O ( N N ) O(N\sqrt N) O(NN)。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 30005, maxs = 10000005;
struct node
{
int b, p, d;
} Q[maxs];
int N, M, S, T, L, R;
bool vsb[maxn];
vector<int> pos[maxn];
bitset<maxn> vs[maxn];
inline void psh(int b, int p, int d)
{
if (!vs[b][p])
Q[++R] = node{
b, p, d}, vs[b][p] = 1;
}
inline void upd(int b, int p, int d)
{
psh(b, p, d);
if (!vsb[b])
{
vsb[b] = 1;
for (auto &q : pos[b])
psh(b, q, d);
}
}
int bfs()
{
vsb[S] = 1;
L = 1, R = 0;
for (auto &p : pos[S])
psh(S, p, 0);
while (L <= R)
{
node &t = Q[L++];
if (t.b == T)
return t.d;
if (t.b - t.p >= 0)
upd(t.b - t.p, t.p, t.d + 1);
if (t.b + t.p < N)
upd(t.b + t.p, t.p, t.d + 1);
}
return -1;
}
int main()
{
scanf("%d%d", &N, &M);
for (int i = 0, b, p; i < M; ++i)
{
scanf("%d%d", &b, &p), pos[b].push_back(p);
if (i == 0)
S = b;
if (i == 1)
T = b;
}
printf("%d\n", bfs());
return 0;
}