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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
#include <vector> #include <algorithm> #include <iostream> #include <array> #include <queue>
using ll = long long;
struct line { ll k, b;
line(ll k, ll b) : k(k), b(b) {}
double intersect(const line& l) const { return 1.0 * (l.b - b) / (k - l.k); }
bool operator <(const line& rhs) const { if (k == rhs.k) return b > rhs.b; return k < rhs.k; }
ll operator ()(ll x) const { return k * x + b; } };
struct ConvexHull { std::vector<double> points; std::vector<line> lines;
int size() { return points.size(); }
void reset() { points.clear(); lines.clear(); }
void init(const line& l) { points.push_back(-1e9); lines.push_back(l); }
void addLine(const line& l) { if (points.size() == 0) { points.push_back(-1e9); lines.push_back(l); return; } while (lines.size() >= 2 && l.intersect(lines[lines.size() - 2]) <= points.back()) { points.pop_back(); lines.pop_back(); } points.push_back(l.intersect(lines.back())); lines.push_back(l); }
ll query(int x, int id) { return lines[id](x); }
ll query(int x) { int id = upper_bound(points.begin(), points.end(), x) - points.begin() - 1; return lines[id](x); } };
int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr);
int n, m, k; std::cin >> n >> m >> k;
std::vector<std::vector<std::pair<int, ll>>> adj(n); for (int i = 0; i < m; ++i) { int u, v; ll w; std::cin >> u >> v >> w; u--, v--; adj[u].emplace_back(v, w); adj[v].emplace_back(u, w); }
std::vector<ll> dis(n, 0x3f3f3f3f3f3f3f3f); std::function<void(const std::vector<int>&)> dijkstra = [&](const std::vector<int>& start) { std::priority_queue<std::pair<ll, int>, std::vector<std::pair<ll, int>>, std::greater<>> q; for (auto i: start)q.emplace(dis[i], i); while (!q.empty()) { auto [dist, u] = q.top(); q.pop(); if (dis[u] != dist)continue; for (auto [v, w]: adj[u]) { if (w + dis[u] < dis[v]) { dis[v] = w + dis[u]; q.emplace(dis[v], v); } } } };
dis[0] = 0; dijkstra((std::vector<int>(1)));
for (int i = 0; i < k; ++i) { ConvexHull ch; std::vector<int> change; for (ll j = 0; j < n; ++j) { ch.addLine(line(-2 * j, dis[j] + j * j)); } int id = 0; for (ll u = 1; u < n; u++) { while (id + 1 < ch.size() && ch.query(u, id + 1) < ch.query(u, id)) id++; ll cur = ch.query(u, id) + ll(u) * u; if (cur < dis[u]) { change.push_back(u); dis[u] = cur; } } dijkstra(change); } for (int i = 0; i < n; ++i)std::cout << dis[i] << " \n"[i == n - 1]; return 0; }
|