Skip to content
Snippets Groups Projects
Commit bb991088 authored by Ondřej Mička's avatar Ondřej Mička
Browse files

Graphs: heavy-light (almost)

parent 4edf7a62
No related branches found
No related tags found
No related merge requests found
......@@ -4,6 +4,8 @@
\fi
\def\TODO{{\bf TODO}}
\def\LCA{\op{LCA}}
\chapter[graphs]{Representation of graphs}
In this chapter we will peek into the area of data structures for representation of
......@@ -16,28 +18,30 @@ E)$, where each vertex~$v$ has weight~$w(v)\in\R$.\foot{We could also had weight
instead.} We would like to support following operations:
\tightlist{o}
\:\em{path query} --- find the vertex with minimum weight on a path $u\to
v$;\foot{Generally, we can use any associative operation, instead of minimum.}
v$;\foot{Generally, we can use any associative operation instead of minimum.}
\:\em{point update} --- set $w(v) \leftarrow c\in\R$;
\:\em{path update} --- increase weight of each vertex on path $u\to v$ by $\delta\in\R$;
\:\em{structural update} --- connect/disconnect two trees via edge $(u,v)$.
\endlist
\section[path]{Static path}
As a warm-up we build a data structure for $F$ being a path and without structural
As a warm-up we build a data structure for $F$ being a static path, without structural
updates. This will also be an important building block for the more general case.
Let us denote the vertices $v_1, \dots, v_n$ according to the position on the path and let
us denote $w_i = w(v_i)$. \TODO\foot{maybe change initial notation} We build an interval
us denote $w_i = w(v_i)$. \TODO\foot{maybe change initial notation} We build an range
tree~$T$ over the weights $w_1, \dots, w_n$. That is, $T$ is a complete binary tree with
$w_1,\dots w_n$ in its leaves (in this order) and inner nodes contain the minimum of their
children. Note that each node represents a subpath of~$F$ with leaves being the single
vertices.
\TODO picture of path and the interval tree
\figure[]{interval-tree.pdf}{}{\TODO}
\TODO perhaps reference the lecture notes on details about range trees
\TODO picture of path and the range tree
\figure[]{range-tree.pdf}{}{\TODO}
% temporary sketch, not in repository
\theorem{Static path representation via interval tree can perform \em{path query},
\theorem{Static path representation via range tree can perform \em{path query},
\em{point update}
and \em{path update} in $\O(\log n)$ time.
}
......@@ -73,4 +77,66 @@ always traverse the tree top-down in order to see correct values in the nodes.
% temporary sketch, not in repository
\qed
\section[hld]{Heavy-light decomposition}
Now we are ready build data structure for static trees using \em{heavy-light
decomposition}. We assume our tree $F$ is rooted and we orient all edges
up, towards the root \TODO\foot{maybe unnecessary now}.
\defn{
Let~$F$ be a rooted tree. For any vertex~$v$ we define $s(v)$ to be the size of subtree
rooted at~$v$ (including~$v$). Let~$u$ be a child of~$v$, we say the edge~$(v,u)$ is
\em{heavy} iff $s(u) \ge s(v)/2$, otherwise we say $(v,u)$ is \em{light}. Finally, a
\em{heavy path} is simply a path containing only heavy edges.
}
\obs{
For any vertex~$v$, there is at most one heavy edge from~$v$ to its children. Therefore,
each vertex~$v$ lies on exactly one heavy path (the path can consist of only~$v$).
}
\obs{
Any root-to-leaf path in~$F$ contains at most $\log n$ light edges.
}
This gives us the decomposition of the tree into heavy paths that connected via light
edges. The decomposition can be easily found using depth-first search in
linear time.
We represent each heavy path using the range tree structure for static path from the
previous chapter. The root of each range tree will also store the light edge that leads up
from the top of the path and connects it with other heavy path.
\TODO decomposition example
The following lemma gives a recipe on how to evaluate path queries and updates:
\lemma{
Every path $x\to y$ in~$F$ can be partitioned into $\O(\log n)$ light edges and $\O(\log n)$
subpaths of heavy paths.
}
\proof
If the path is top-down we have $O(\log n)$ light edges by the previous observation and
these edges split the path into $O(\log n)$ heavy subpaths. Otherwise, path $x\to y$ can
be divided into two top-down paths at the lowest common ancestor of $x$ and $y$.
\qed
Thus, we just partition the query (update) into $\O(\log n)$ queries on heavy paths plus
light edges. As each subquery can be evaluated in $\O(\log n)$ we get $\O(\log^2 n)$ in
total.
However, there is a catch. To calculate the partitioning, we need to calculate lowest
common ancestor of~$x$~and~$y$ ($\LCA(x,y)$).
\TODO
\section[linkcut]{Link-cut trees}
\TODO
\section{Application: Faster Dinic's algorithm}
\TODO
\endchapter
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment