willy108

Unfortunate FST

Jul 25th, 2024
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.86 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define sz(v) int(v.size())
  5. #define ar array
  6. typedef long long ll;
  7. const int N = 1e5+10, MOD = 998244353;
  8.  
  9. struct Line {
  10. mutable ll k, m, p;
  11. bool operator<(const Line& o) const { return k < o.k; }
  12. bool operator<(ll x) const { return p < x; }
  13. };
  14.  
  15. struct LineContainer : multiset<Line, less<>> {
  16. // (for doubles, use inf = 1/.0, div(a,b) = a/b)
  17. static const ll inf = LLONG_MAX;
  18. ll div(ll a, ll b) { // floored division
  19. return a / b - ((a ^ b) < 0 && a % b); }
  20. bool isect(iterator x, iterator y) {
  21. if (y == end()) return x->p = inf, 0;
  22. if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
  23. else x->p = div(y->m - x->m, x->k - y->k);
  24. return x->p >= y->p;
  25. }
  26. void add(ll k, ll m) {
  27. k *= -1, m *= -1;
  28. auto z = insert({k, m, 0}), y = z++, x = y;
  29. while (isect(y, z)) z = erase(z);
  30. if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
  31. while ((y = x) != begin() && (--x)->p >= y->p)
  32. isect(x, erase(y));
  33. }
  34. ll query(ll x) {
  35. assert(!empty());
  36. auto l = *lower_bound(x);
  37. return -(l.k * x + l.m);
  38. }
  39. };
  40.  
  41. const ll INF = 1e10+10;
  42.  
  43. template<class T> using min_pq = priority_queue<T, vector<T>, greater<T>>;
  44.  
  45. void solve() {
  46. int n, m, k; cin >> n >> m >> k;
  47. vector<vector<pair<int, ll>>> adj(n);
  48. while (m--) {
  49. int a, b; ll w; cin >> a >> b >> w, --a, --b;
  50. adj[a].push_back({b, w});
  51. adj[b].push_back({a, w});
  52. }
  53. vector<ll> pdp(n, INF); pdp[0] = 0;
  54.  
  55. auto relax = [&]() {
  56. vector<ll> ndp(n, INF);
  57.  
  58. min_pq<pair<ll, int>> pq;
  59. for (int i = 0; i < n; i++) {
  60. pq.push({pdp[i], i});
  61. ndp[i] = pdp[i];
  62. }
  63.  
  64. while (sz(pq)) {
  65. auto [d, c] = pq.top(); pq.pop();
  66. if (d != ndp[c]) continue;
  67. for (auto [nxt, w] : adj[c]) if (ndp[nxt] > ndp[c] + w) {
  68. ndp[nxt] = ndp[c] + w;
  69. pq.push({ndp[nxt], nxt});
  70. }
  71. }
  72. swap(ndp, pdp);
  73. };
  74.  
  75. for (int rep = 0; rep < k; rep++) {
  76. relax();
  77.  
  78. auto ndp = pdp;
  79. LineContainer lines;
  80.  
  81. lines.clear();
  82. for (int i = 0; i < n; i++) {
  83. // a[j] + i^2 + j^2 - 2*i*j
  84. if (i) ndp[i] = min(ndp[i], lines.query(i) + (long long) i * i);
  85. lines.add(-2 * i, pdp[i] + (long long) i * i);
  86. }
  87.  
  88. lines.clear();
  89. for (int i = n-1; i >= 0; i--) {
  90. // a[j] + i^2 + j^2 - 2*i*j
  91. if (i < n-1) ndp[i] = min(ndp[i], lines.query(i) + (long long) i * i);
  92. lines.add(-2 * i, pdp[i] + (long long) i * i);
  93. }
  94.  
  95. swap(pdp, ndp);
  96. }
  97. relax();
  98. for (int x : pdp) cout << x << ' ';
  99. cout << '\n';
  100. }
  101. int main() {
  102. ios::sync_with_stdio(false); cin.tie(0);
  103. int T = 1;
  104. // cin >> T;
  105. while (T--) solve();
  106. }
Advertisement
Add Comment
Please, Sign In to add comment