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>
#define Loop(x,l,r) for (ll x = (l); x < (ll)(r); ++x)
#define LoopR(x,l,r) for (ll x = (r)-1; x >= (ll)(l); --x)
typedef long long ll;
typedef std::pair<int, int> pii;
typedef std::pair<ll , ll > pll;
using namespace std;
const int N = 250'010;
const int L = 1600;
bool has_watch[N];
int watch_size[N];
int watch_ind[N];
int watch_guard[N];
int watch_size_list[L];
int n, m, k;
int *nxt[L][L];
void calc_nxt(int step, int size)
{
if (nxt[step][size])
return;
nxt[step][size] = new int[size];
int cnt = 0;
for (int beg=0; cnt < size; ++beg) {
vector<pii> vec;
int x = beg;
do {
while (vec.size() && vec.back().first > x)
vec.pop_back();
nxt[step][size][x] = vec.size()?
cnt - vec.back().second:
-1;
vec.push_back({x, cnt});
++cnt;
x = x-step%size;
x = x<0?x+size:x;
} while (x != beg);
}
}
vector<int> A[N];
int norm_dis[N];
void bfs(int s)
{
memset(norm_dis, -1, sizeof(norm_dis));
vector<int> q = {s};
Loop (i,0,q.size()) {
int v = q[i];
for (int u : A[v]) {
if (norm_dis[u] != -1)
continue;
norm_dis[u] = norm_dis[v] + 1;
q.push_back(u);
}
}
}
vector<ll> dis[N];
void upS(int from, int v, ll d, set<tuple<ll,int,int>> &Set)
{
int md = has_watch[v]? d % watch_size[v]: 0;
if (d >= dis[v][md])
return;
if (has_watch[v] && md == watch_ind[v])
return;
if (has_watch[from] && has_watch[v] && watch_guard[from] == watch_guard[v] && watch_ind[from] == md && (watch_ind[v] == md-1 || watch_ind[v] == md+watch_size[v]-1))
return;
Set.erase ({dis[v][md]+norm_dis[v], md, v});
dis[v][md] = d;
Set.insert({dis[v][md]+norm_dis[v], md, v});
}
void up3(int v, int u, ll d, set<tuple<ll,int,int>> &Set)
{
int step = watch_size[v];
int size = watch_size[u];
int x = (d + size - watch_ind[u]) % size;
for (;;) {
upS(v, u, d+1, Set);
ll cnt = nxt[step][size][x];
if (cnt == -1)
break;
d += cnt*step;
x = (x + cnt*step) % size;
}
}
ll dij(int s, int t)
{
set<tuple<ll,int,int>> Set;
Loop (i,0,N)
dis[i] = vector<ll>(has_watch[i]?watch_size[i]:1, (ll)1e17);
dis[s][0] = 0;
Set.insert({dis[s][0]+norm_dis[s], 0, s});
while (Set.size()) {
auto [dard, md, v] = *Set.begin();
Set.erase(Set.begin());
ll d = dis[v][md];
if (v == t)
return d;
upS(v, v, d+1, Set);
for (int u : A[v]) {
if (has_watch[u] && has_watch[v]) {
up3(v, u, d, Set);
} else if (has_watch[u]) {
upS(v, u, d+1, Set);
int wait = watch_ind[u] - d%watch_size[u];
wait = wait<0?wait+watch_size[u]:wait;
upS(v, u, d+1+wait, Set);
} else {
upS(v, u, d+1, Set);
}
}
}
return -1;
}
int main()
{
cin.tie(0) -> sync_with_stdio(false);
cin >> n >> m;
Loop (i,0,m) {
int v, u;
cin >> v >> u;
--v; --u;
A[v].push_back(u);
A[u].push_back(v);
}
cin >> k;
Loop (i,0,k) {
int l;
cin >> l;
watch_size_list[i] = l;
Loop (j,0,l) {
int v;
cin >> v;
--v;
watch_size[v] = l;
watch_ind[v] = j;
has_watch[v] = 1;
watch_guard[v] = i;
}
}
Loop (i,0,k) Loop (j,0,k)
calc_nxt(watch_size_list[i], watch_size_list[j]);
bfs(n-1);
ll ans = dij(0, n-1);
if (ans == -1)
cout << "impossible\n";
else
cout << ans << '\n';
}
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |