1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| #include <bits/stdc++.h>
#define int int64_t
const int kMaxN = 155;
int n, m; int g[kMaxN][kMaxN], dis[kMaxN]; bool vis[kMaxN]; std::vector<std::tuple<int, int, int>> ed; std::vector<std::pair<int, int>> G[kMaxN];
struct Matrix { int n, m; std::bitset<kMaxN> a[kMaxN];
void set(int _n, int _m) { n = _n, m = _m; } friend Matrix operator *(const Matrix &m1, const Matrix &m2) { static Matrix ret; assert(m1.m == m2.n); ret.set(m1.n, m2.m); for (int i = 1; i <= m1.n; ++i) ret.a[i].reset(); for (int i = 1; i <= m1.n; ++i) { for (int k = 1; k <= m1.m; ++k) { if (m1.a[i][k]) ret.a[i] |= m2.a[k]; } } return ret; } } S, M, O;
void dijkstra() { std::priority_queue<std::pair<int, int>> q; for (int i = 1; i <= n; ++i) { dis[i] = 1e18, vis[i] = 0; if (S.a[1][i]) q.emplace(dis[i] = 0, i); } for (; !q.empty();) { auto [d, u] = q.top(); q.pop(); if (vis[u]) continue; vis[u] = 1; for (auto [v, w] : G[u]) { if (M.a[u][v] && dis[v] > dis[u] + 1) { dis[v] = dis[u] + 1, q.emplace(-dis[v], v); } } } }
Matrix qpow(Matrix bs, int idx) { Matrix ret = O; for (; idx; idx >>= 1, bs = bs * bs) if (idx & 1) ret = ret * bs; return ret; }
void dickdreamer() { std::cin >> n >> m; memset(g, 0x3f, sizeof(g)); for (int i = 1; i <= m; ++i) { int u, v, w; std::cin >> u >> v >> w; ed.emplace_back(w, u, v); G[u].emplace_back(v, w); g[u][v] = w; } std::sort(ed.begin(), ed.end()); int lst = 0, ans = 1e18; S.set(1, n), M.set(n, n), O.set(n, n); for (int i = 1; i <= n; ++i) O.a[i][i] = 1; S.a[1][1] = 1; for (int i = 0; i < m; ++i) { auto [w, u, v] = ed[i]; if (ans < w) break; if (w != lst) S = S * qpow(M, w - lst); M.a[u][v] = 1, lst = w; dijkstra(); ans = std::min(ans, w + dis[n]); } if (ans >= 1e15) std::cout << "Impossible\n"; else std::cout << ans << '\n'; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; while (T--) dickdreamer(); return 0; }
|