結果
問題 | No.2764 Warp Drive Spacecraft |
ユーザー |
|
提出日時 | 2024-05-18 10:42:58 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 372 ms / 3,000 ms |
コード長 | 3,834 bytes |
コンパイル時間 | 2,459 ms |
コンパイル使用メモリ | 209,780 KB |
最終ジャッジ日時 | 2025-02-21 15:42:29 |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 35 |
ソースコード
#include <bits/stdc++.h>using namespace std;using ll = long long;//min_verclass LiChaoTree{struct Line{long long a, b;long long get(long long x){return a * x + b; }Line(long long a, long long b) : a(a), b(b) {}};struct Node {Node *left, *right;Line line;Node(Line line) : left(nullptr), right(nullptr), line(line) {}};const long long inf = 1ll << 60;const Line inf_line = Line{0, inf};Node *root;long long lx, rx;Node* _add_line(Node *nd, Line line, long long l, long long r){if(l == r) return nullptr;if(nd == nullptr) return new Node(line);long long m = (l + r) >> 1;bool left = (line.get(l) <= nd->line.get(l));bool mid = (line.get(m) <= nd->line.get(m));bool right = (line.get(r) <= nd->line.get(r));if(left && right)nd->line = line;if(left == right)return nd;if(mid) std::swap(nd->line, line);if(left != mid){nd->left = _add_line(nd->left, line, l, m);}else{nd->right = _add_line(nd->right, line, m, r);}return nd;}Node* _add_segment_line(long long a, long long b, Node *nd, Line line, long long l, long long r) {if(r <= a || b <= l) return nd;if(a <= l && r <= b) return _add_line(nd, line, l, r);if(nd == nullptr) nd = new Node(inf_line);long long m = (l + r) >> 1;nd->left = _add_segment_line(a, b, nd->left, line, l, m);nd->right = _add_segment_line(a, b, nd->right, line, m, r);return nd;}long long query(long long x, long long l, long long r){Node *nd = root;long long res = inf;while(r > l && nd != nullptr) {long long m = (l + r) >> 1;res = std::min(res, nd->line.get(x));if(x < m) {r = m;nd = nd->left;} else {l = m;nd = nd->right;}}return res;}public:// [xl, xr)LiChaoTree(long long lx, long long rx) : lx(lx), rx(rx), root(nullptr) {}void add_line(long long a, long long b) {Line line(a, b);root = _add_line(root, line, lx, rx);}void add_segment_line(long long a, long long b, long long l, long long r) {Line line = Line{a, b};root = _add_segment_line(l, r, root, line, lx, rx);}long long get(long long x) {return query(x, lx, rx);}};int main(){ios::sync_with_stdio(false);cin.tie(0);int n, m;cin >> n >> m;vector<int> w(n);LiChaoTree LCT(0, 1 << 30);vector<ll> dp(n, 1ll << 60);vector<vector<pair<int,ll>>> g(n);priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<pair<ll,int>>> pq;for(auto &&v : w) cin >> v;for(int i = 0; i < m; i++){int u, v;ll t;cin >> u >> v >> t;u--, v--;g[u].emplace_back(v, t);g[v].emplace_back(u, t);}dp[0] = 0;pq.emplace(0, 0);while(!pq.empty()){auto [d, v] = pq.top();pq.pop();if(d > dp[v]) continue;LCT.add_line(w[v], d);for(auto &&[u, w] : g[v]){if(d + w >= dp[u]) continue;dp[u] = d + w;pq.emplace(dp[u], u);}}for(int i = 0; i < n; i++){dp[i] = min(dp[i], LCT.get(w[i]));pq.emplace(dp[i], i);}while(!pq.empty()){auto [d, v] = pq.top();pq.pop();if(d > dp[v]) continue;LCT.add_line(w[v], d);for(auto &&[u, w] : g[v]){if(d + w >= dp[u]) continue;dp[u] = d + w;pq.emplace(dp[u], u);}}cout << dp[n - 1] << '\n';}