結果
問題 | No.386 貪欲な領主 |
ユーザー |
![]() |
提出日時 | 2017-09-17 13:22:48 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 39 ms / 2,000 ms |
コード長 | 5,168 bytes |
コンパイル時間 | 1,211 ms |
コンパイル使用メモリ | 105,316 KB |
実行使用メモリ | 13,308 KB |
最終ジャッジ日時 | 2024-11-08 01:52:52 |
合計ジャッジ時間 | 2,210 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 16 |
ソースコード
#include <cstdio>#include <cassert>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <map>#include <set>#include <functional>#include <stack>#include <queue>#include <tuple>#define getchar getchar_unlocked#define putchar putchar_unlocked#define _rep(_1, _2, _3, _4, name, ...) name#define rep2(i, n) rep3(i, 0, n)#define rep3(i, a, b) rep4(i, a, b, 1)#define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c))#define rep(...) _rep(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__)using namespace std;using i64 = long long;using u8 = unsigned char;using u32 = unsigned;using u64 = unsigned long long;using f80 = long double;int get_int() {int c, n;while ((c = getchar()) < '0');n = c - '0';while ((c = getchar()) >= '0') n = n * 10 + (c - '0');return n;}class RootedTree {private:struct InputEdge { int from, to; };template <typename T>struct Range {struct Iterator {T& operator * () const { return *iter; }bool operator != (const Iterator& rhs) const { return iter != rhs.iter; }void operator ++ () { ++iter; }T* operator + (int i) const { return iter + i; }size_t operator - (const Iterator rhs) const { return iter - rhs.iter; }T* iter;};Range(T* f, T* l) : first({f}), last({l}) {}T operator [] (int i) { return *(first + i); }size_t size() const { return last - first; }Iterator& begin() { return first; }Iterator& end() { return last; }Iterator first, last;};public:RootedTree(int N, int M=0): N(N), ofs(N + 1),par(N), vid(N), head(N), heavy(N), len(N) {if (M > 0) in.reserve(M);}Range<int> operator [] (int u) {return Range<int>(&edges[ofs[u]], &edges[ofs[u + 1]]);}void add_edge(int u, int v) { in.push_back({u, v}); }void build(int root) { init(), dfs(root), bfs(root); }int lca(int u, int v) const {for (; head[u] != head[v]; u = par[head[u]]) if (vid[u] < vid[v]) swap(u, v);return vid[u] > vid[v] ? v : u;}pair< vector<int>, vector< pair<int, int> > > signed_euler_tour(int root) {range.resize(N);tour.resize(2 * N);int id = 0;e_rec(root, id);return {tour, range};}vector<int> get_path(int u, int v) const {vector<int> pu, pv; int s = 0;while (head[u] != head[v]) {if (vid[u] < vid[v]) swap(u, v), swap(pu, pv), s ^= 1;for (int w = par[head[u]]; u != w; u = par[u]) pu.push_back(u);}if (vid[u] < vid[v]) swap(u, v), swap(pu, pv), s ^= 1;for (; vid[u] != vid[v]; u = par[u]) pu.push_back(u);pu.push_back(u);if (s) swap(pu, pv);reverse(pv.begin(), pv.end());for (auto& w : pv) pu.push_back(w);return pu;}int parent(int u) const { return par[u]; }vector<int> get_order() const {vector<int> order(N);for (int i = 0; i < N; ++i) order[vid[i]] = i;return order;}private:void e_rec(int u, int& id, int p=-1) {tour[id] = u;range[u].first = id++;for (auto& v : (*this)[u]) if (v != p) e_rec(v, id, u);tour[id] = ~u;range[u].second = id++;}void bfs(int root) {vector<int> que(N);int qh = 0, qt = 0, id = 0;que[qt++] = root;for (; qh < qt; ) {int u = que[qh++];for (int v = u; v >= 0; v = heavy[v]) {vid[v] = id++, head[v] = u;for (auto& w : (*this)[v]) if (w != par[v] && w != heavy[v]) que[qt++] = w;}len[u] = id - vid[u];}}int dfs(int u, int p=-1) {int s = 1, best = 0, h = -1;par[u] = p;for (auto& v : (*this)[u]) if (v != p) {int c = dfs(v, u);if (c > best) best = c, h = v;s += c;}heavy[u] = h;return s;}void init() {edges.resize(2 * in.size());for (auto& e : in) ofs[e.from + 1]++, ofs[e.to + 1]++;for (int i = 1; i <= N; ++i) ofs[i] += ofs[i - 1];for (auto& e : in) edges[ofs[e.from]++] = e.to, edges[ofs[e.to]++] = e.from;for (int i = N; i > 0; --i) ofs[i] = ofs[i - 1];ofs[0] = 0;}private:int N;vector<InputEdge> in;vector<int> ofs, edges;vector<int> par, vid, head, heavy, len;vector< pair<int, int> > range;vector<int> tour;};void solve() {int N;while (~scanf("%d", &N)) {auto g = RootedTree(N);rep(i, N - 1) {int u = get_int(), v = get_int();g.add_edge(u, v);}g.build(0);vector<int> cost(N); rep(i, N) cost[i] = get_int();vector<int> cumu(N);int M = get_int();rep(i, M) {int u = get_int(), v = get_int(), c = get_int();int lca = g.lca(u, v), p = g.parent(lca);cumu[u] += c;cumu[v] += c;cumu[lca] -= c;if (p >= 0) cumu[p] -= c;}auto order = g.get_order();i64 ans = 0;rep(i, N) {int u = order[N - 1 - i], p = g.parent(u);ans += i64(cumu[u]) * cost[u];if (p >= 0) cumu[p] += cumu[u];}printf("%lld\n", ans);}}int main() {clock_t beg = clock();solve();clock_t end = clock();fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC);return 0;}