Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
ds2-notes
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
datovky
ds2-notes
Commits
bb991088
Commit
bb991088
authored
4 years ago
by
Ondřej Mička
Browse files
Options
Downloads
Patches
Plain Diff
Graphs: heavy-light (almost)
parent
4edf7a62
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
om-graphs/graphs.tex
+72
-6
72 additions, 6 deletions
om-graphs/graphs.tex
with
72 additions
and
6 deletions
om-graphs/graphs.tex
+
72
−
6
View file @
bb991088
...
...
@@ -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
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment