Skip to content

Compress tree #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6ff9e79
saving progress
lrvideckis Jul 1, 2024
fef6a44
saving progress
lrvideckis Jul 1, 2024
c40002e
Update mono_st.rs
lrvideckis Jul 1, 2024
7a899cc
saving progress
lrvideckis Jul 1, 2024
fd59fe1
saving progress
lrvideckis Jul 1, 2024
90572e9
saving progress
lrvideckis Jul 1, 2024
96635dd
another assert
lrvideckis Jul 1, 2024
882bdba
remove
lrvideckis Jul 1, 2024
03682e8
add test
lrvideckis Jul 1, 2024
2eb1c12
asdf
lrvideckis Jul 1, 2024
72658ee
finish
lrvideckis Jul 1, 2024
8eb0abe
better
lrvideckis Jul 1, 2024
c656614
fix
lrvideckis Jul 1, 2024
153cec0
uncomment
lrvideckis Jul 1, 2024
dc0c736
Update mono_st.rs
lrvideckis Jul 3, 2024
c87a544
Update mono_range.rs
lrvideckis Jul 3, 2024
574b24f
Update mono_st.rs
lrvideckis Jul 3, 2024
e1f81e5
fix
lrvideckis Jul 3, 2024
8b1614a
change style
lrvideckis Jul 3, 2024
35a88ad
nit
lrvideckis Jul 3, 2024
7646a4a
change
lrvideckis Jul 3, 2024
2dc1895
nits
lrvideckis Jul 3, 2024
0f85db9
different style
lrvideckis Jul 3, 2024
460f332
golf
lrvideckis Jul 3, 2024
fc29bdf
consistency with c++ PTC
lrvideckis Jul 3, 2024
55b71bd
finish doc for mono st
lrvideckis Jul 3, 2024
fd3b167
simplify test
lrvideckis Jul 3, 2024
00acb23
add
lrvideckis Jul 3, 2024
cbb0b82
add docs for mono range
lrvideckis Jul 3, 2024
5f49d8c
fix typo
lrvideckis Jul 3, 2024
016e02e
nit
lrvideckis Jul 3, 2024
c97712a
fix
lrvideckis Jul 3, 2024
54936fb
nit to docs
lrvideckis Jul 4, 2024
62e4fc6
now ACs
lrvideckis Jul 4, 2024
2b56c9d
virt tree
lrvideckis Jul 6, 2024
438c6f7
finish docs
lrvideckis Jul 6, 2024
3a1fb27
finished test
lrvideckis Jul 6, 2024
ff31ec1
make dist const
lrvideckis Jul 6, 2024
38343f0
consistent var names
lrvideckis Jul 7, 2024
3f89810
Merge branch 'main' into compress_tree
lrvideckis Jul 8, 2024
69c561c
Merge branch 'main' into compress_tree
lrvideckis Jul 17, 2024
b9afd08
Merge branch 'main' into compress_tree
cameroncuster Jul 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ path = "examples/data_structures/range_container_handmade.rs"
name = "mono_st"
path = "examples/monotonic/mono_st.rs"

[[example]]
name = "hld_aux_tree"
path = "examples/graphs/hld_aux_tree.rs"

[[example]]
name = "count_rects"
path = "examples/monotonic/count_rects.rs"
Expand Down
80 changes: 80 additions & 0 deletions examples/graphs/hld_aux_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_B

use proconio::input;
use programming_team_code_rust::graphs::hld::HLD;
use std::collections::VecDeque;

fn main() {
input! {
n: usize,
edges: [(usize, usize, u32); n - 1],
}

let mut adj_weighted = vec![vec![]; n];
let mut adj = vec![vec![]; n];
for &(u, v, w) in &edges {
adj[u].push(v);
adj[v].push(u);
adj_weighted[u].push((v, w));
adj_weighted[v].push((u, w));
}
let adj_weighted = adj_weighted;

let mut dist = vec![0; n];
{
fn dfs(u: usize, p: Option<usize>, adj_weighted: &[Vec<(usize, u32)>], dist: &mut [u32]) {
for &(v, w) in &adj_weighted[u] {
if Some(v) == p {
continue;
}
dist[v] = w + dist[u];
dfs(v, Some(u), adj_weighted, dist);
}
}
dfs(0, None, &adj_weighted, &mut dist);
}
let dist = dist;

let hld = HLD::new(&mut adj, true);

let weighted_dist = |u: usize, v: usize| -> u32 {
let lc = hld.lca(u, v);
dist[u] + dist[v] - 2 * dist[lc]
};

let mut diam_u = 0;
for i in 1..n {
if weighted_dist(0, i) > weighted_dist(0, diam_u) {
diam_u = i;
}
}
let mut diam_v = 0;
for i in 1..n {
if weighted_dist(diam_u, i) > weighted_dist(diam_u, diam_v) {
diam_v = i;
}
}

for u in 0..n {
let (par, to_node) = hld.aux_tree(vec![diam_u, diam_v, u]);
let mut aux_adj = vec![vec![]; par.len()];
for i in 1..par.len() {
let edge_w = dist[to_node[i]] - dist[to_node[par[i]]];
aux_adj[i].push((par[i], edge_w));
aux_adj[par[i]].push((i, edge_w));
}
let mut q = VecDeque::new();
q.push_back((to_node.iter().position(|&x| x == u).unwrap(), None, 0));
let mut res = 0;
while let Some((node, parent, curr_dist)) = q.pop_front() {
res = res.max(curr_dist);
for &(v, w) in &aux_adj[node] {
if Some(v) == parent {
continue;
}
q.push_back((v, Some(node), curr_dist + w));
}
}
println!("{}", res);
}
}
39 changes: 39 additions & 0 deletions src/graphs/hld.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! # Heavy Light Decomposition

use crate::graphs::dfs_order::{get_dfs_postorder, get_dfs_preorder};
use crate::monotonic::mono_st::mono_st;
use std::ops::Range;

/// # Example
Expand Down Expand Up @@ -201,4 +202,42 @@ impl HLD {
None
}
}

/// # Auxiliary Tree
///
/// - see <https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/CompressTree.h>
///
/// # Example
/// ```
/// use programming_team_code_rust::graphs::hld::HLD;
///
/// let n = 5;
/// let mut adj = vec![vec![]; n];
/// for (u, v) in [(0,1), (1,2), (2,3), (2,4)] {
/// adj[u].push(v);
/// adj[v].push(u);
/// }
///
/// let hld = HLD::new(&mut adj, false);
///
/// let (par, to_node) = hld.aux_tree(vec![0, 3, 4]);
/// // 0, 1, .., par.len()-1 is a topological/dfs order of aux tree
/// assert_eq!(par, [usize::MAX, 0, 1, 1]);
/// assert_eq!(to_node, [0, 2, 3, 4]);
/// ```
///
/// # Complexity
/// - k = nodes.len()
/// - Time: O((k log k) + (k log n))
/// - Space: O(k)
pub fn aux_tree(&self, mut nodes: Vec<usize>) -> (Vec<usize>, Vec<usize>) {
nodes.sort_by(|&u, &v| self.tin[u].cmp(&self.tin[v]));
let siz = nodes.len();
for i in 1..siz {
nodes.push(self.lca(nodes[i - 1], nodes[i]));
}
nodes.sort_by(|&u, &v| self.tin[u].cmp(&self.tin[v]));
nodes.dedup();
(mono_st(&nodes, |&u, &v| self.in_sub(u, v)), nodes)
}
}
Loading