This blog post is a submission for the Codeforces Month of Blog Posts Pt. III challenge. Thank you cadmiumky for the initiative!
Introduction Problem
ICPC North America Championship 2025, Problem B - Circle of LeafLink: https://qoj.ac/contest/2041/problem/11357
Given a rooted tree with $$$n$$$ nodes, construct a undirected graph as follows:
- For each edge $$$(u, v)$$$ in the tree, add an edge between $$$u$$$ and $$$v$$$.
- For each leaf node $$$u$$$ in the tree, add an edge between $$$u$$$ and the root.
Please calculate the number of spanning trees of the resulting graph, modulo $$$998\,244\,353$$$.
Note that the resulting graph may contain multiple edges between the same pair of nodes.
Constraints:
Before tackling the problem, let's first try some simple examples.
The notation we use will also be introduced in the examples, so please try to understand them carefully.
Example 1
Hmmm, the graph is just two nodes connected by $$$5$$$ multiple edges.
Answer to Example 1Simple! We can only choose exactly one of the $$$5$$$ edges, so there are $$$5$$$ spanning trees in total.
Example 2
Here, the $$$\times x$$$ means there are $$$x$$$ multiple edges between the two nodes.
Answer to Example 2 - There are $$$1 \cdot 5 \cdot 7$$$ spanning trees if we ignore the edges between $$$1$$$ and $$$2$$$, and
- there are $$$3 \cdot 1 \cdot 7$$$ spanning trees if we ignore the edges between $$$2$$$ and $$$3$$$, and
- there are $$$3 \cdot 5 \cdot 1$$$ spanning trees if we ignore the edges between $$$1$$$ and $$$3$$$.
In total, there are $$$1 \cdot 5 \cdot 7 + 3 \cdot 1 \cdot 7 + 3 \cdot 5 \cdot 1 = 71$$$ spanning trees.
What's Next?Let the $$$i^\text{th}$$$ edge $$$e_i = (u_i, v_i)$$$, we will use the notation $$$\langle a_i, \overline{a_i} \rangle$$$ to denote the number of ways such that nodes $$$u_i$$$ and $$$v_i$$$ are connected exactly once by the $$$i^\text{th}$$$ edge and the number of ways such that they are not directly connected.
In a normal graph, we can either choose or not choose each edge, so the values on each edge is $$$\langle 1, 1 \rangle$$$.
If we combine $$$k$$$ multiple edges together, we will have $$$k$$$ ways to include the edge, and $$$1$$$ way to not include any of them. Thus, the values on each edge will be $$$\langle k, 1 \rangle$$$.

That is the case when we combine normal $$$\langle 1, 1 \rangle$$$ edges. How do we deal with the edges with any $$$\langle a, \overline{a} \rangle$$$?
Example 3
Answer to Example 3The number of ways such that the two nodes are connected only by the below edge is $$$a \overline{b}$$$; the number of ways such that the two nodes are connected only by the above edge is $$$\overline{a} b$$$, so the answer is $$$\overline{a} b + a \overline{b}$$$.
What if we want to just use an edge to represent the information of these two edges? Can we compress the informations on these two edges together?

Note that if we want the two nodes to not be connected via these edges, we can only exclude both of them.
Answer to Example 3a
- If we want the two nodes to not be connected via these edges, we can only exclude both of them, which contributes $$$\overline{a} \overline{b}$$$ to the answer.
- If we want the two nodes to be connected via these edges, we can either exclude the first edge and include the second edge, or include the first edge and exclude the second edge, which contributes $$$\overline{a} b + a \overline{b}$$$ to the answer.
Thus, the multiple edges $$$\langle a, \overline{a} \rangle$$$ and $$$\langle b, \overline{b} \rangle$$$ can be combined into a single edge $$$\langle \overline{a} b + a \overline{b}, \overline{a} \overline{b} \rangle$$$.
Example 4
Answer to Example 4The answer is $$$a b$$$.
Again, can you combine these two edges together?

What kind of information does the edge maintain?The new edge $$$(2, 3)$$$ stores the information in the dashed part, which includes edges $$$(1, 2)$$$, $$$(1, 3)$$$ and the node $$$1$$$.
Since the process is the same as the compress operation in Top Tree, we can just borrow the name and call the dashed part a cluster and the nodes incident to the cluster boundary nodes.
In this case, the cluster is the middle node $$$1$$$ and the two edges $$$(1, 2)$$$ and $$$(1, 3)$$$, which has two boundary nodes $$$2$$$ and $$$3$$$.
Each edge in the graph stores the information of a cluster, when we try to compress a node with degree $$$2$$$, we will combine the two clusters together, and the new edge will store the information of the combined cluster.
In this problem, we want to maintain the number of spanning trees of the graph, so the information stored on the edge is (1.) the number of ways such that the boundary nodes $$$u_i$$$ and $$$v_i$$$ are connected via the cluster (i.e. count the spanning trees in the cluster), and (2.) the number of ways such that they are not connected via the cluster while each node in the cluster is still connected to either of the boundary nodes.
Answer to Example 4a
- To make nodes $$$2$$$ and $$$3$$$ connected, we must include both edges $$$(1, 2)$$$ and $$$(1, 3)$$$, which contributes $$$a b$$$ to the answer.
- To make nodes $$$2$$$ and $$$3$$$ not connected, we can either exclude edge $$$(1, 2)$$$ or exclude edge $$$(1, 3)$$$, which contributes $$$\overline{a} b + a \overline{b}$$$ to the answer.
- Note that we cannot exclude both edges, otherwise the cluster will be disconnected to the rest of the graph, which is not allowed.
Thus, the middle node can be contracted, and the two edges $$$\langle a, \overline{a} \rangle$$$ and $$$\langle b, \overline{b} \rangle$$$ will be combined into a single edge $$$\langle a b, \overline{a} b + a \overline{b} \rangle$$$.
Enough examples, let's try to solve the problem now.
Solution Case 0: The graph has only one node, then the answer is $$$\text{dp}[G]$$$.
Case 1: There are leaves (nodes with degree $$$1$$$) in the graph. We will try to prune the leaves.
- Let $$$u_i$$$ be such a leaf. We define $$$G'$$$ as the graph with $$$u_i$$$ removed ($$$G' = G - { u_i } - { (u_i, v_i) }$$$).
- Since the $$$i^\text{th}$$$ edge must be chosen in order for the graph to be connected, we have $$$\text{dp}[G'] = \text{dp}[G] \times a_i$$$.
Case 2: There are multiple edges in the graph. We will try to twist multiple edges.
- Let the $$$i^\text{th}$$$ edge be equal to the $$$j^\text{th}$$$ edge, i.e., $$$(u_i, v_i) = (u_j, v_j)$$$.
- We can compress these two edges into a single edge with value $$$\langle \overline{a_i} a_j + a_i \overline{a_j}, \overline{a_i} \overline{a_j} \rangle$$$.
- Since we are neither forced to choose nor forced to exclude the edge, $$$\text{dp}[G']$$$ remains unchanged.
Case 3: There are nodes with degree $$$2$$$. We will try to compress nodes with degree $$$2$$$.
- Let $$$x$$$ be the node with degree $$$2$$$, and the $$$i^\text{th}$$$ edge $$$(u_i = x, v_i)$$$ and the $$$j^\text{th}$$$ edge $$$(u_j = x, v_j)$$$ be the only two edges incident to node $$$x$$$.
- We can contract these two edges into a single new edge $$$(v_i, v_j)$$$ with value $$$\langle a_i a_j, \overline{a_i} a_j + a_i \overline{a_j} \rangle$$$.
- Since we are neither forced to choose nor forced to exclude the edge, $$$\text{dp}[G']$$$ remains unchanged.
Case 4: Every nodes in the graph has degree at least $$$3$$$.
- I do not acknowledge a way to reduce the graph even smaller, so we'll have to stop here.
Wait, what? Is the solution incomplete?
Actually, in this problem, we can actually prove that Case 4 will never happen!
Simple ProofLet $$$h_u$$$ be the number of edges between node $$$u$$$ and $$$r =_\text{def} \text{root}$$$.
For any node $$$u \ne r$$$:
- if its $$$h_u \gt 1$$$, then we can apply Case 2 to twist the multiple edges between $$$u$$$ and $$$r$$$.
- if it is a leaf, then we can apply Case 1 to prune it.
- if it is a leaf when we ignore the edge between $$$u$$$ and $$$r$$$, then we can apply Case 3 to compress it. The two neighboring nodes of $$$u$$$ are its parent $$$\text{par}_u$$$ and $$$r$$$, so we will remove $$$(u, \text{par}_u)$$$ and $$$(u, r)$$$ and add a new edge $$$(\text{par}_u, r)$$$. Note that $$$h_{\text{par}_u}$$$ will increase by $$$1$$$ after the compression.
Therefore, the reduction process will never stop until we have no leaves other than the root $$$r$$$. We will apply Case 0 and get the answer to the problem.
Accepted Code: https://qoj.ac/submission/2028367
Implementation

Code: https://qoj.ac/submission/2028368
Depends on problem requirement, the Info struct and the three operations Prune, Twist and Compress may be defined differently. Basically, the Info struct should store the information of a cluster, and the three operations should be defined according to the meaning of the information stored in the Info struct.
Code (Structure Definition and Operations)struct Info { int T, F; };
int Prune(const Info &a) {
return a.T;
}
Info Twist(const Info &a, const Info &b) {
return Info {
.T = (a.F * b.T + a.T * b.F) % mod,
.F = (a.F * b.F) % mod
};
}
Info Compress(const Info &a, const Info &b) {
return Info {
.T = (a.T * b.T) % mod,
.F = (a.F * b.T + a.T * b.F) % mod
};
}
For simplicity, we will use vector<map<int, Info>> to store the adjacency lists and the info on the edge to represent the graph, and use two queues to maintain the nodes with degree $$$1$$$ or $$$2$$$.
Here is the pseudo code of the reduction process:
Pseudo Code (Reduction Process)while the queues are not both empty:
if there are nodes with degree 1:
let now be such node
let (u, info) be the only edge incident to node now
/// Case 1, prune leaves ///
combine the answer with Prune(info)
remove the edge (now, u) from the graph
if the degree of node u becomes 1 or 2:
push it to the corresponding queue
else if there are nodes with degree 2:
let now be such node
let (u, info_u) and (v, info_v) be the two edges incident to node now
/// Case 3, compress two edges ///
let info = Compress(info_u, info_v)
if the edge (u, v) already exists:
/// Case 2, twist multiple edges ///
let info_uv be the info on edge (u, v)
info_uv = Twist(info, info_uv)
else:
add a new edge (u, v) with info
remove the edges (now, u) and (now, v) from the graph
if the degree of node u becomes 1 or 2:
push it to the corresponding queue
if the degree of node v becomes 1 or 2:
push it to the corresponding queue
Generalization
General Series-Parallel Graphs (GSPG)
If a graph can be constructed by repeatedly applying the following operations starting from a single node, then it is called a General Series-Parallel Graph.
- Add a new isolated node.
- Add a new node with an edge connecting it to any existing node.
- It is the inverse operation of prune.
- Duplicate any existing edge by adding a new edge between the same pair of nodes.
- It is the inverse operation of twist.
- Subdivide any existing edge by adding a new node in the middle of the edge.
- It is the inverse operation of compress.
Random Facts - Series-Parallel Graphs are a special case of General Series-Parallel Graphs, where we start from an edge, and are not allowed to apply the first two operations.
- Planar graphs are $$$K_5$$$-minor-free and $$$K_{3,3}$$$-minor-free.
- General Series-Parallel graphs are $$$K_4$$$-minor-free.
- Any General Series-Parallel graph is also a Planar graph.
- Outer Planar graphs are $$$K_4$$$-minor-free and $$$K_{2,3}$$$-minor-free.
- Outer Planar graphs are Planar graphs with an embedding such that all nodes are on the outer face.
- Any Outer Planar graph is also a General Series-Parallel graph.
Trees are GSPG, cactuses are GSPG, outer planar graphs are GSPG!
If a graph is a GSPG, then we can apply the reduction process to it until there is only one node left.
Connected Graphs with Small $$$m - n$$$
Observe the operations:
- in Prune operation, $$$n \gets n - 1$$$ and $$$m \gets m - 1$$$;
- in Twist operation, $$$n \gets n$$$ and $$$m \gets m - 1$$$;
- in Compress operation, $$$n \gets n - 1$$$ and $$$m \gets m - 1$$$.
The value of $$$m - n$$$ will never increase and will decrease by $$$1$$$ per Twist operations.
When the reduction process stops, we have the degree of each node at least $$$3$$$, so we can yield $$$2m' \ge 3n'$$$.
Suppose $$$m - n \le k$$$ in the original graph, then we have $$$m' - n' \le k$$$ and $$$2m' \ge 3n'$$$, which yields $$$n' \le 2k$$$ and $$$m' \le 3k$$$.
Thus, if $$$m - n$$$ is small, we can apply the reduction process until there are at most $$$2k$$$ nodes and $$$3k$$$ edges left, and then solve the problem by brute force.
Values on Boundary Nodes
Sometimes, we may want to maintain some values on the boundary nodes of the cluster, and the operations should also update these values together with the information on the edge.
Practice
If you know some problem that can be solved by the method, please share it in the comments.
(I will try to put some problems on polygon when I have time...)
Library Checker - Tree Decomposition (Width 2)Link: https://judge.yosupo.jp/problem/tree_decomposition_width_2
The class of graphs with treewidth at most $$$2$$$ is exactly the same as the class of graphs that do not contain $$$K_4$$$ as a minor, which is also the same as the class of General Series-Parallel Graphs.
Basically, this is an implementation checker of the reduction process.
DAG Counting (No Link)Given an undirected connected graph with $$$n$$$ nodes and $$$m$$$ edges, there are $$$2^m$$$ ways to assign a direction to each edge.
Please calculate the number of DAGs among these $$$2^m$$$ directed graphs, modulo $$$998\,244\,353$$$.
Constraints:
- $$$n \le 100\,000$$$
- $$$m \le n + 10$$$
Mutual Tests 2019, Round 3, Problem C - ParkLink: https://qoj.ac/contest/313/problem/8460
Given a connected GSPG with $$$n$$$ nodes and $$$m$$$ edges, there are two values $$$w_u$$$ and $$$s_u$$$ on each node $$$u$$$, and two values $$$c_e$$$ and $$$d_e$$$ on each edge $$$e$$$.
You should color each node with either white or silver, each node colored white/silver will contribute $$$w_u$$$/$$$s_u$$$ to the answer, and each edge whose endpoints are colored the same/differently will contribute $$$c_e$$$/$$$d_e$$$ to the answer.
There are $$$Q$$$ modifications, each modification will change the value of $$$w_u$$$, $$$s_u$$$, $$$c_e$$$ or $$$d_e$$$ for some node $$$u$$$ or edge $$$e$$$, and after each modification, you should calculate the maximum possible sum of values among all $$$2^n$$$ possible colorings of the nodes.
Constraints:
- $$$n \le 100\,000$$$
- $$$Q \le 100\,000$$$
YTP 2025 Senior, Problem 19 - Polygon TriangulationLink: https://oj.ntucpc.org/problems/969
There are $$$n$$$ points placed at the vertices of a regular $$$n$$$-gon, numbered $$$0, 1, \ldots, n-1$$$. Initially, there is an edge (a straight line segment) between every $$$i$$$ and $$$(i+1) \bmod n$$$.
For example, when $$$n = 6$$$, the initial state looks like this:
![]()
Then there are $$$n-3$$$ operations. In each operation, Sakiko selects a pair of vertices $$$(u_i, v_i)$$$ and draw a straight line segment through $$$u$$$ and $$$v$$$, with the guarantee that this segment does not cross any previously drawn segment (it may intersect at endpoints).
Output $$$n-2$$$ nonnegative integers $$$q_0, q_1, \ldots, q_{n-3}$$$, where $$$q_i$$$ denotes the number of spanning trees of the graph after the $$$i$$$-th operation, taken modulo $$$998\,244\,353$$$.
Constraints:
Notes: There are subtasks to test the solution without modifications.
References
- https://github.com/enkerewpo/OI-Public-Library/blob/master/IOI%E4%B8%AD%E5%9B%BD%E5%9B%BD%E5%AE%B6%E5%80%99%E9%80%89%E9%98%9F%E8%AE%BA%E6%96%87/%E5%9B%BD%E5%AE%B6%E9%9B%86%E8%AE%AD%E9%98%9F2019%E8%AE%BA%E6%96%87%E9%9B%86.pdf, page 165-191 (Chinese)
- https://zhuanlan.zhihu.com/p/32413108 (Chinese)
- https://oi-wiki.org/ds/top-tree/ (Chinese)
- https://en.wikipedia.org/wiki/Series%E2%80%93parallel_graph