From 14ba54f903e407101a6f79719cc6f1ade6521703 Mon Sep 17 00:00:00 2001 From: shogo314 Date: Sat, 29 Jun 2024 00:26:54 +0900 Subject: [PATCH 01/12] [Add] rerooting-dp.hpp --- cpp/rerooting-dp.hpp | 100 +++++++++++++++++++++++++++++++++++++++++ test/aoj-1595.test.cpp | 16 +++++++ 2 files changed, 116 insertions(+) create mode 100644 cpp/rerooting-dp.hpp create mode 100644 test/aoj-1595.test.cpp diff --git a/cpp/rerooting-dp.hpp b/cpp/rerooting-dp.hpp new file mode 100644 index 0000000..5ea2396 --- /dev/null +++ b/cpp/rerooting-dp.hpp @@ -0,0 +1,100 @@ +#pragma once + +/** + * @file rerooting-dp.hpp + * @brief 全方位木DP + */ +#include +#include + +#include "tree.hpp" + +/** + * @brief 全方位木DP + * dp[u] = addnode(merge(addedge(dp[v1], g_uv1, uv1.id), merge(addedge(dp[v2], g_uv2, uv2.id), ...)), u) v_iはuの子 + * + * @tparam E 可換モノイド + * @tparam V DPの型 + * @param tree + * @param e 可換モノイドの単位元 + * @param merge (E,E)->E 可換 + * @param addedge (V,Cost,int)->E + * @param addnode (E,int)->V + * @return std::vector + */ +template +std::vector rerooting_dp(const Tree& tree, E e, Merge merge, AddEdge addedge, AddNode addnode) { + static_assert(std::is_invocable_r_v); + static_assert(std::is_invocable_r_v); + static_assert(std::is_invocable_r_v); + assert(tree.n > 0); + RootedTree rooted(tree, 0); + std::vector subdp(rooted.n); + for (int u : rooted.postorder) { + E tmp = e; + for (auto edge : rooted.child[u]) { + tmp = merge(tmp, addedge(subdp[edge.dst], edge.cost, edge.id)); + } + subdp[u] = addnode(tmp, u); + } + std::vector dp(rooted.n); + std::vector pe(rooted.n, e); + for (int u : rooted.preorder) { + const auto& ch = rooted.child[u]; + std::vector ri(ch.size() + 1, e); + for (size_t i = ch.size(); i > 0; i--) { + ri[i - 1] = merge(ri[i], addedge(subdp[ch[i - 1].dst], ch[i - 1].cost, ch[i - 1].id)); + } + dp[u] = addnode(merge(pe[u], ri[0]), u); + E le = e; + for (size_t i = 0; i < ch.size(); i++) { + pe[ch[i].dst] = addedge(addnode(merge(pe[u], merge(le, ri[i + 1])), u), ch[i].cost, ch[i].id); + le = merge(le, addedge(subdp[ch[i].dst], ch[i].cost, ch[i].id)); + } + } + return dp; +} + +/** + * @brief 最も遠い頂点までの距離 + */ +template +inline std::vector farthest_node_dist(const Tree& tree) { + return rerooting_dp( + tree, + Cost{}, + [](Cost a, Cost b) { return std::max(a, b); }, + [](Cost a, Cost c, int i) { return a + c; }, + [](Cost a, int i) { return a; }); +} + +/** + * @brief 他の全ての頂点との距離の合計 + */ +template +inline std::vector distance_sums(const Tree& tree) { + using P = typename std::pair; + auto tmp = rerooting_dp( + tree, + P{{}, 0}, + [](P a, P b) { return P{a.first + b.first, a.second + b.second}; }, + [](P a, Cost c, int i) { return P{a.first + a.second * c, a.second}; }, + [](P a, int i) { return P{a.first, a.second + 1}; }); + std::vector res; + res.reserve(tree.n); + for (const P& s : tmp) res.push_back(s.first); + return res; +} + +/** + * @brief その頂点を含む連結な部分グラフの個数 + */ +template +inline std::vector connected_subgraph_count(const Tree& tree) { + return rerooting_dp( + tree, + V(1), + [](V a, V b) { return a * b; }, + [](V a, Cost c, int i) { return a + 1; }, + [](V a, int i) { return a; }); +} diff --git a/test/aoj-1595.test.cpp b/test/aoj-1595.test.cpp new file mode 100644 index 0000000..bfedbab --- /dev/null +++ b/test/aoj-1595.test.cpp @@ -0,0 +1,16 @@ +#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1595" + +#include + +#include "../cpp/rerooting-dp.hpp" + +int main() { + int N, M; + std::cin >> N; + Tree tree(N); + tree.read(); + auto ans = farthest_node_dist(tree); + for (int i = 0; i < N; i++) { + std::cout << 2 * N - 2 - ans[i] << std::endl; + } +} From f7e01645e7d709e46584fc5cc9424b4162fa3650 Mon Sep 17 00:00:00 2001 From: shogo314 Date: Sat, 29 Jun 2024 00:31:47 +0900 Subject: [PATCH 02/12] [fix] test and assert --- cpp/rerooting-dp.hpp | 1 - test/aoj-1595.test.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/rerooting-dp.hpp b/cpp/rerooting-dp.hpp index 5ea2396..77a2621 100644 --- a/cpp/rerooting-dp.hpp +++ b/cpp/rerooting-dp.hpp @@ -27,7 +27,6 @@ std::vector rerooting_dp(const Tree& tree, E e, Merge merge, AddEdge ad static_assert(std::is_invocable_r_v); static_assert(std::is_invocable_r_v); static_assert(std::is_invocable_r_v); - assert(tree.n > 0); RootedTree rooted(tree, 0); std::vector subdp(rooted.n); for (int u : rooted.postorder) { diff --git a/test/aoj-1595.test.cpp b/test/aoj-1595.test.cpp index bfedbab..c59988d 100644 --- a/test/aoj-1595.test.cpp +++ b/test/aoj-1595.test.cpp @@ -5,7 +5,7 @@ #include "../cpp/rerooting-dp.hpp" int main() { - int N, M; + int N; std::cin >> N; Tree tree(N); tree.read(); From 56170e0a22b8b4fc395b1301d80c169f3dd6f416 Mon Sep 17 00:00:00 2001 From: GitHub Date: Fri, 28 Jun 2024 15:32:48 +0000 Subject: [PATCH 03/12] [auto-verifier] verify commit f7e01645e7d709e46584fc5cc9424b4162fa3650 --- .verify-helper/timestamps.remote.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 7562f33..a8924a4 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -1,4 +1,5 @@ { +"test/aoj-1595.test.cpp": "2024-06-29 00:31:47 +0900", "test/aoj-3314.test.cpp": "2023-10-12 08:50:40 +0900", "test/aoj-alds1-3-c.test.py": "2023-09-05 02:43:56 +0900", "test/aoj-cgl-2-b.test.cpp": "2023-09-07 23:01:33 +0900", From 0e95013302b6f70c97fca2ac21fe47d62c4ecd27 Mon Sep 17 00:00:00 2001 From: shogo314 Date: Sat, 29 Jun 2024 00:36:39 +0900 Subject: [PATCH 04/12] [update] delete unused i --- cpp/rerooting-dp.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/rerooting-dp.hpp b/cpp/rerooting-dp.hpp index 77a2621..faab241 100644 --- a/cpp/rerooting-dp.hpp +++ b/cpp/rerooting-dp.hpp @@ -63,8 +63,8 @@ inline std::vector farthest_node_dist(const Tree& tree) { tree, Cost{}, [](Cost a, Cost b) { return std::max(a, b); }, - [](Cost a, Cost c, int i) { return a + c; }, - [](Cost a, int i) { return a; }); + [](Cost a, Cost c, int) { return a + c; }, + [](Cost a, int) { return a; }); } /** @@ -77,8 +77,8 @@ inline std::vector distance_sums(const Tree& tree) { tree, P{{}, 0}, [](P a, P b) { return P{a.first + b.first, a.second + b.second}; }, - [](P a, Cost c, int i) { return P{a.first + a.second * c, a.second}; }, - [](P a, int i) { return P{a.first, a.second + 1}; }); + [](P a, Cost c, int) { return P{a.first + a.second * c, a.second}; }, + [](P a, int) { return P{a.first, a.second + 1}; }); std::vector res; res.reserve(tree.n); for (const P& s : tmp) res.push_back(s.first); @@ -94,6 +94,6 @@ inline std::vector connected_subgraph_count(const Tree& tree) { tree, V(1), [](V a, V b) { return a * b; }, - [](V a, Cost c, int i) { return a + 1; }, - [](V a, int i) { return a; }); + [](V a, Cost c, int) { return a + 1; }, + [](V a, int) { return a; }); } From 805717431d5f443e280771d1155de081e2973f3d Mon Sep 17 00:00:00 2001 From: GitHub Date: Fri, 28 Jun 2024 15:37:52 +0000 Subject: [PATCH 05/12] [auto-verifier] verify commit 0e95013302b6f70c97fca2ac21fe47d62c4ecd27 --- .verify-helper/timestamps.remote.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index a8924a4..58a9008 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -1,5 +1,5 @@ { -"test/aoj-1595.test.cpp": "2024-06-29 00:31:47 +0900", +"test/aoj-1595.test.cpp": "2024-06-29 00:36:39 +0900", "test/aoj-3314.test.cpp": "2023-10-12 08:50:40 +0900", "test/aoj-alds1-3-c.test.py": "2023-09-05 02:43:56 +0900", "test/aoj-cgl-2-b.test.cpp": "2023-09-07 23:01:33 +0900", From 609038c523f8222b0960d9df965b87e3cc0df1f2 Mon Sep 17 00:00:00 2001 From: shogo314 Date: Sat, 29 Jun 2024 11:50:03 +0900 Subject: [PATCH 06/12] [update] V = E --- cpp/rerooting-dp.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cpp/rerooting-dp.hpp b/cpp/rerooting-dp.hpp index faab241..9d8dec9 100644 --- a/cpp/rerooting-dp.hpp +++ b/cpp/rerooting-dp.hpp @@ -6,7 +6,6 @@ */ #include #include - #include "tree.hpp" /** @@ -22,7 +21,7 @@ * @param addnode (E,int)->V * @return std::vector */ -template +template std::vector rerooting_dp(const Tree& tree, E e, Merge merge, AddEdge addedge, AddNode addnode) { static_assert(std::is_invocable_r_v); static_assert(std::is_invocable_r_v); @@ -59,7 +58,7 @@ std::vector rerooting_dp(const Tree& tree, E e, Merge merge, AddEdge ad */ template inline std::vector farthest_node_dist(const Tree& tree) { - return rerooting_dp( + return rerooting_dp( tree, Cost{}, [](Cost a, Cost b) { return std::max(a, b); }, @@ -73,7 +72,7 @@ inline std::vector farthest_node_dist(const Tree& tree) { template inline std::vector distance_sums(const Tree& tree) { using P = typename std::pair; - auto tmp = rerooting_dp( + auto tmp = rerooting_dp( tree, P{{}, 0}, [](P a, P b) { return P{a.first + b.first, a.second + b.second}; }, @@ -90,7 +89,7 @@ inline std::vector distance_sums(const Tree& tree) { */ template inline std::vector connected_subgraph_count(const Tree& tree) { - return rerooting_dp( + return rerooting_dp( tree, V(1), [](V a, V b) { return a * b; }, From 66ff501f3ac83ceaea39c6c328773a030351653d Mon Sep 17 00:00:00 2001 From: GitHub Date: Sat, 29 Jun 2024 02:51:08 +0000 Subject: [PATCH 07/12] [auto-verifier] verify commit 609038c523f8222b0960d9df965b87e3cc0df1f2 --- .verify-helper/timestamps.remote.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 58a9008..3f2af33 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -1,5 +1,5 @@ { -"test/aoj-1595.test.cpp": "2024-06-29 00:36:39 +0900", +"test/aoj-1595.test.cpp": "2024-06-29 11:50:03 +0900", "test/aoj-3314.test.cpp": "2023-10-12 08:50:40 +0900", "test/aoj-alds1-3-c.test.py": "2023-09-05 02:43:56 +0900", "test/aoj-cgl-2-b.test.cpp": "2023-09-07 23:01:33 +0900", From cf3ee7c2cc82cc9c310d2a7c87a5658a4d2275ea Mon Sep 17 00:00:00 2001 From: shogo314 Date: Sat, 29 Jun 2024 13:20:16 +0900 Subject: [PATCH 08/12] =?UTF-8?q?[update]=20=E5=86=97=E9=95=B7=E3=81=AAmer?= =?UTF-8?q?ge=E3=81=AE=E7=B0=A1=E7=95=A5=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cpp/rerooting-dp.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/rerooting-dp.hpp b/cpp/rerooting-dp.hpp index 9d8dec9..bc62bd6 100644 --- a/cpp/rerooting-dp.hpp +++ b/cpp/rerooting-dp.hpp @@ -44,9 +44,9 @@ std::vector rerooting_dp(const Tree& tree, E e, Merge merge, AddEdge ad ri[i - 1] = merge(ri[i], addedge(subdp[ch[i - 1].dst], ch[i - 1].cost, ch[i - 1].id)); } dp[u] = addnode(merge(pe[u], ri[0]), u); - E le = e; + E le = pe[u]; for (size_t i = 0; i < ch.size(); i++) { - pe[ch[i].dst] = addedge(addnode(merge(pe[u], merge(le, ri[i + 1])), u), ch[i].cost, ch[i].id); + pe[ch[i].dst] = addedge(addnode(merge(le, ri[i + 1]), u), ch[i].cost, ch[i].id); le = merge(le, addedge(subdp[ch[i].dst], ch[i].cost, ch[i].id)); } } From 489765dc6cd32a6a9bd090d0cc967056c0b971f3 Mon Sep 17 00:00:00 2001 From: GitHub Date: Sat, 29 Jun 2024 04:21:19 +0000 Subject: [PATCH 09/12] [auto-verifier] verify commit cf3ee7c2cc82cc9c310d2a7c87a5658a4d2275ea --- .verify-helper/timestamps.remote.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 3f2af33..4633469 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -1,5 +1,5 @@ { -"test/aoj-1595.test.cpp": "2024-06-29 11:50:03 +0900", +"test/aoj-1595.test.cpp": "2024-06-29 13:20:16 +0900", "test/aoj-3314.test.cpp": "2023-10-12 08:50:40 +0900", "test/aoj-alds1-3-c.test.py": "2023-09-05 02:43:56 +0900", "test/aoj-cgl-2-b.test.cpp": "2023-09-07 23:01:33 +0900", From a521b75b16fa4aa471b78e6eb699c6de47ae5092 Mon Sep 17 00:00:00 2001 From: shogo314 <80336945+shogo314@users.noreply.github.com> Date: Tue, 13 Aug 2024 01:21:52 +0900 Subject: [PATCH 10/12] doxygenno --- cpp/rerooting-dp.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/rerooting-dp.hpp b/cpp/rerooting-dp.hpp index bc62bd6..1a501f3 100644 --- a/cpp/rerooting-dp.hpp +++ b/cpp/rerooting-dp.hpp @@ -10,7 +10,7 @@ /** * @brief 全方位木DP - * dp[u] = addnode(merge(addedge(dp[v1], g_uv1, uv1.id), merge(addedge(dp[v2], g_uv2, uv2.id), ...)), u) v_iはuの子 + * dp[u] = addnode(merge(addedge(dp[v1], uv1.cost, uv1.id), merge(addedge(dp[v2], uv2.cost, uv2.id), ...)), u) v_iはuの子 * * @tparam E 可換モノイド * @tparam V DPの型 From d541c3c2e303a4bc4bd7bab99b0d5a1f53660fe5 Mon Sep 17 00:00:00 2001 From: shogo314 <80336945+shogo314@users.noreply.github.com> Date: Tue, 13 Aug 2024 01:24:17 +0900 Subject: [PATCH 11/12] size_t -> std::size_t --- cpp/rerooting-dp.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/rerooting-dp.hpp b/cpp/rerooting-dp.hpp index 1a501f3..d9200ee 100644 --- a/cpp/rerooting-dp.hpp +++ b/cpp/rerooting-dp.hpp @@ -5,6 +5,7 @@ * @brief 全方位木DP */ #include +#include #include #include "tree.hpp" @@ -40,12 +41,12 @@ std::vector rerooting_dp(const Tree& tree, E e, Merge merge, AddEdge ad for (int u : rooted.preorder) { const auto& ch = rooted.child[u]; std::vector ri(ch.size() + 1, e); - for (size_t i = ch.size(); i > 0; i--) { + for (std::size_t i = ch.size(); i > 0; i--) { ri[i - 1] = merge(ri[i], addedge(subdp[ch[i - 1].dst], ch[i - 1].cost, ch[i - 1].id)); } dp[u] = addnode(merge(pe[u], ri[0]), u); E le = pe[u]; - for (size_t i = 0; i < ch.size(); i++) { + for (std::size_t i = 0; i < ch.size(); i++) { pe[ch[i].dst] = addedge(addnode(merge(le, ri[i + 1]), u), ch[i].cost, ch[i].id); le = merge(le, addedge(subdp[ch[i].dst], ch[i].cost, ch[i].id)); } From d09e1fe451d2ef54fe83854148000aaa379ced03 Mon Sep 17 00:00:00 2001 From: GitHub Date: Mon, 12 Aug 2024 16:25:31 +0000 Subject: [PATCH 12/12] [auto-verifier] verify commit d541c3c2e303a4bc4bd7bab99b0d5a1f53660fe5 --- .verify-helper/timestamps.remote.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 4633469..a3cf204 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -1,5 +1,5 @@ { -"test/aoj-1595.test.cpp": "2024-06-29 13:20:16 +0900", +"test/aoj-1595.test.cpp": "2024-08-13 01:24:17 +0900", "test/aoj-3314.test.cpp": "2023-10-12 08:50:40 +0900", "test/aoj-alds1-3-c.test.py": "2023-09-05 02:43:56 +0900", "test/aoj-cgl-2-b.test.cpp": "2023-09-07 23:01:33 +0900",