This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define endl '\n'
#define fi first
#define se second
#define For(i, l, r) for (int i = l; i < r; i++)
#define ForE(i, l, r) for (int i = l; i <= r; i++)
#define FordE(i, l, r) for (int i = l; i >= r; i--)
#define Fora(v, a) for (auto v: a)
#define bend(a) a.begin(), a.end()
#define isz(a) ((signed)a.size())
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef vector <int> vi;
typedef vector <pii> vpii;
typedef vector <vi> vvi;
const int N = 3e4 + 5, S = sqrt(N) + 1;
struct Node{
int d, u, j;
Node(int d = 0, int u = 0, int j = 0): d(d), u(u), j(j){
}
};
bool operator< (const Node& lhs, const Node& rhs){
if (lhs.d != rhs.d) return lhs.d < rhs.d;
if (lhs.u != rhs.u) return lhs.u < rhs.u;
return lhs.j < rhs.j;
}
bool operator> (const Node& lhs, const Node& rhs){
if (lhs.d != rhs.d) return lhs.d > rhs.d;
if (lhs.u != rhs.u) return lhs.u > rhs.u;
return lhs.j > rhs.j;
}
int n, m;
int b[N], p[N];
vi pos[N]; // cac doge j co b_j = i
vpii adj[N]; // cac canh i ma p_i > S - 1
int dist[N][S]; // j = 1 -> S - 1: jump length j, j = 0: other jump
priority_queue <Node, vector <Node>, greater <Node>> pq;
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
// freopen("KEK.inp", "r", stdin);
// freopen("KEK.out", "w", stdout);
cin >> n >> m;
For(i, 0, m){
cin >> b[i] >> p[i];
}
For(i, 0, m){
if (p[i] > S - 1){
int u, d;
u = b[i] + p[i]; d = 1;
while (u < n){
adj[b[i]].emplace_back(u, d);
u += p[i]; d++;
}
u = b[i] - p[i]; d = 1;
while (u >= 0){
adj[b[i]].emplace_back(u, d);
u -= p[i]; d++;
}
}
else{
pos[b[i]].emplace_back(p[i]);
}
}
memset(dist, 0x3f, sizeof(dist));
dist[b[0]][0] = 0;
pq.push(Node(dist[b[0]][0], b[0], 0));
while (!pq.empty()){
Node t = pq.top(); pq.pop();
if (dist[t.u][t.j] != t.d){
continue;
}
if (t.u == b[1]){
cout << t.d << endl;
return 0;
}
if (t.j){
if (dist[t.u][0] > t.d){
dist[t.u][0] = t.d;
pq.push(Node(dist[t.u][0], t.u, 0));
}
if (t.u + t.j < n and dist[t.u + t.j][t.j] > t.d + 1){
dist[t.u + t.j][t.j] = t.d + 1;
pq.push(Node(dist[t.u + t.j][t.j], t.u + t.j, t.j));
}
if (t.u - t.j >= 0 and dist[t.u - t.j][t.j] > t.d + 1){
dist[t.u - t.j][t.j] = t.d + 1;
pq.push(Node(dist[t.u - t.j][t.j], t.u - t.j, t.j));
}
}
else{
Fora(&edge, adj[t.u]){
if (dist[edge.fi][0] > t.d + edge.se){
dist[edge.fi][0] = t.d + edge.se;
pq.push(Node(dist[edge.fi][0], edge.fi, 0));
}
}
Fora(&idx, pos[t.u]){
if (dist[t.u][idx] > t.d){
dist[t.u][idx] = t.d;
pq.push(Node(dist[t.u][idx], t.u, idx));
}
}
}
}
cout << -1 << endl;
}
/*
n dinh, m con doge. doge thu i bat dau tu b_i, nhay sang trai/phai p_i buoc. hoi khoang cach nho nhat nhay tu doge 0 sang 1.
neu nhu p_i <= S - 2: bfs trong dist[u][p_i]
ngoai ra: nhay giua cac dinh vi co toi da N / S dinh den duoc
n * sqrt(n) * log ~ 5e6 * log, co the qua
co the toi uu thanh n * s duoc ko = bfs thay dijkstra???
cu thu dijkstra truoc thoi :pray:
==================================================+
INPUT: |
--------------------------------------------------|
--------------------------------------------------|
==================================================+
OUTPUT: |
--------------------------------------------------|
--------------------------------------------------|
==================================================+
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |