Skip to content

Commit

Permalink
refactor: dfs once to solve tree_diam
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiphereth-A committed Jan 11, 2024
1 parent 7df6d18 commit 5c5bb82
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions src/code/tree/diam.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,45 @@
#ifndef TIFALIBS_TREE_DIAM
#define TIFALIBS_TREE_DIAM

#include "dfs_info.hpp"
#include "../graph/dfs.hpp"

namespace tifa_libs::graph {

// {u, v, diam}
template <class G>
constexpr auto tree_diam(G &tree) {
auto _ = tree.root;
tree_dfs_info<G> info;
auto d = info.template reset_dfs_info<td_dis>(tree).dis;
u32 u = tree.root = (u32)std::distance(d.begin(), std::max_element(d.begin(), d.end()));
d = info.template reset_dfs_info<td_dis>(tree).dis;
u32 v = (u32)std::distance(d.begin(), std::max_element(d.begin(), d.end()));
tree.root = _;
return std::make_tuple(u, v, d[v]);
constexpr auto tree_diam(G const& tree) {
using T = typename G::weight_type;

u32 n = (u32)tree.g.size();
vec<T> mdis(n), mdis2(n);
vec<u32> midx(n), midx2(n);
std::iota(midx.begin(), midx.end(), 0), std::iota(midx2.begin(), midx2.end(), 0);

auto init = [](u32, u32) {};
auto pre = [](u32, u32) {};
auto prew = [](u32, T const&, u32) {};
auto post = [&](u32 to, u32 u) {
if (T _ = mdis[to] + 1; _ > mdis[u]) {
mdis2[u] = mdis[u], mdis[u] = _;
midx2[u] = midx[u], midx[u] = midx[to];
} else if (_ > mdis2[u]) mdis2[u] = _, midx2[u] = midx2[to];
};
auto postw = [&](u32 to, T const& w, u32 u) {
if (T _ = mdis[to] + w; _ > mdis[u]) {
mdis2[u] = mdis[u], mdis[u] = _;
midx2[u] = midx[u], midx[u] = midx[to];
} else if (_ > mdis2[u]) mdis2[u] = _, midx2[u] = midx2[to];
};
auto ret = [](u32, u32) {};

if constexpr (std::is_base_of_v<alist, G>) dfs(tree, tree.root, init, pre, post, ret);
else dfs(tree, tree.root, init, prew, postw, ret);

u32 u = midx[0], v = midx2[0];
T d = mdis[0] + mdis2[0];
for (u32 i = 1; i < n; ++i)
if (d < mdis[i] + mdis2[i]) u = midx[i], v = midx2[i], d = mdis[i] + mdis2[i];
return std::make_tuple(u, v, d);
}

} // namespace tifa_libs::graph
Expand Down

0 comments on commit 5c5bb82

Please sign in to comment.