結果
問題 | No.386 貪欲な領主 |
ユーザー | te-sh |
提出日時 | 2018-01-19 11:34:30 |
言語 | D (dmd 2.106.1) |
結果 |
AC
|
実行時間 | 318 ms / 2,000 ms |
コード長 | 3,782 bytes |
コンパイル時間 | 891 ms |
コンパイル使用メモリ | 122,876 KB |
実行使用メモリ | 29,644 KB |
最終ジャッジ日時 | 2024-06-12 23:35:11 |
合計ジャッジ時間 | 3,042 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,816 KB |
testcase_01 | AC | 1 ms
6,944 KB |
testcase_02 | AC | 1 ms
6,940 KB |
testcase_03 | AC | 1 ms
6,944 KB |
testcase_04 | AC | 318 ms
29,644 KB |
testcase_05 | AC | 255 ms
22,144 KB |
testcase_06 | AC | 250 ms
22,272 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 31 ms
5,376 KB |
testcase_09 | AC | 4 ms
5,376 KB |
testcase_10 | AC | 1 ms
5,376 KB |
testcase_11 | AC | 1 ms
5,376 KB |
testcase_12 | AC | 2 ms
5,376 KB |
testcase_13 | AC | 7 ms
5,376 KB |
testcase_14 | AC | 259 ms
22,272 KB |
testcase_15 | AC | 287 ms
28,416 KB |
ソースコード
import std.algorithm, std.conv, std.range, std.stdio, std.string; import std.container; // SList, DList, BinaryHeap void readV(T...)(ref T t){auto r=readln.splitter;foreach(ref v;t){v=r.front.to!(typeof(v));r.popFront;}} T[] readArray(T)(size_t n){auto a=new T[](n),r=readln.splitter;foreach(ref v;a){v=r.front.to!T;r.popFront;}return a;} T[] readArrayM(T)(size_t n){auto a=new T[](n);foreach(ref v;a)v=readln.chomp.to!T;return a;} void main() { int n; readV(n); auto g = Graph!int(n); foreach (i; 0..n-1) { int a, b; readV(a, b); g.addEdgeB(a, b); } auto tree = makeTree(g).rootify(0).doubling; auto u = readArrayM!long(n); auto v = new long[](n), q = DList!size_t(0); while (!q.empty) { auto s = q.front; q.removeFront(); foreach (t; tree[s].filter!(t => t != tree.parent[s])) { v[t] = u[t] + v[s]; q.insertBack(t); } } int m; readV(m); auto r = 0L; foreach (i; 0..m) { int a, b; long c; readV(a, b, c); auto l = tree.lca(a, b); r += (v[a] + v[b] - 2 * v[l] + u[l]) * c; } writeln(r); } struct Graph(N = int) { import std.typecons; alias Node = N; Node n; Node[][] g; mixin Proxy!g; this(Node n) { this.n = n; g = new Node[][](n); } void addEdge(Node u, Node v) { g[u] ~= v; } void addEdgeB(Node u, Node v) { g[u] ~= v; g[v] ~= u; } } struct Tree(Graph) { import std.algorithm, std.container, std.typecons; Graph g; mixin Proxy!g; alias Node = g.Node; Node root; Node[] parent; int[] size, depth; this(ref Graph g) { this.g = g; this.n = g.n; } ref auto rootify(Node r) { this.root = r; parent = new Node[](g.n); depth = new int[](g.n); depth[] = -1; struct UP { Node u, p; } auto st1 = SList!UP(UP(r, r)); auto st2 = SList!UP(); while (!st1.empty) { auto up = st1.front, u = up.u, p = up.p; st1.removeFront(); parent[u] = p; depth[u] = depth[p] + 1; foreach (v; g[u]) if (v != p) { st1.insertFront(UP(v, u)); st2.insertFront(UP(v, u)); } } size = new int[](g.n); size[] = 1; while (!st2.empty) { auto up = st2.front, u = up.u, p = up.p; st2.removeFront(); size[p] += size[u]; } return this; } auto children(Node u) { return g[u].filter!(v => v != parent[u]); } } ref auto makeTree(Graph)(Graph g) { return Tree!Graph(g); } struct Doubling(Tree) { import std.algorithm, std.container, std.typecons, std.traits, core.bitop; alias Node = Tree.Node; Tree t; mixin Proxy!t; Node[][] ans; int log2md; this(ref Tree t) { this.t = t; auto n = t.n, sent = n, md = maxDepth(n); log2md = md == 0 ? 1 : md.bsr+1; ans = new Node[][](n, log2md); foreach (i; 0..n) { ans[i][0] = t.parent[i]; ans[i][1..$] = sent; } auto q = SList!Node(t.root); while (!q.empty) { auto u = q.front; q.removeFront(); foreach (i; 1..log2md) { auto v = ans[u][i-1]; if (v == sent) break; ans[u][i] = ans[v][i-1]; } foreach (v; t[u].filter!(v => v != t.parent[u])) q.insertFront(v); } } auto maxDepth(Node n) { auto m = 0; foreach (i; 0..n) m = max(m, t.depth[i]); return m; } auto ancestor(Node u, int k) { for (auto i = 0; k > 0; k >>= 1, ++i) if (k&1) u = ans[u][i]; return u; } auto lca(Node u, Node v) { if (t.depth[u] > t.depth[v]) swap(u, v); if (u == t.root) return u; v = ancestor(v, t.depth[v]-t.depth[u]); if (u == v) return u; foreach_reverse (i; 0..log2md) { if (ans[u][i] != ans[v][i]) { u = ans[u][i]; v = ans[v][i]; } } return t.parent[u]; } } auto doubling(Tree)(Tree tree) { return Doubling!Tree(tree); }