公式

C - Double X 解説 by evima


First, through some observations, we see that the subproblem can be interpreted as a bipartite matching. The reformulation as a bipartite matching is as follows:

Consider trees \(T, U\) as rooted trees with vertex \(k\) as the root.
Let \(b_1, b_2, \dots, b_n\) be the children of vertex \(k\) in tree \(T\).
Let \(c_1, c_2, \dots, c_m\) be the children of vertex \(k\) in tree \(U\).
Consider the following bipartite graph with \(n+m\) vertices and \(N-1\) edges.

  • Vertices in the left part are numbered \(1, 2, \dots, n\).
  • Vertices in the right part are numbered \(1, 2, \dots, m\).
  • For an integer \(i\) satisfying \(1 \leq i \leq N\) and \(i \neq k\), suppose vertex \(i\) belongs to the subtree of \(b_j\) in tree \(T\) and belongs to the subtree of \(c_k\) in tree \(U\). Then, an edge with weight \(A_i\) is placed between left vertex \(j\) and right vertex \(k\).

The minimum weight sum of a size-\(4\) matching in the above bipartite graph is the answer to the subproblem. If no size-\(4\) matching exists, the answer is \(-1\).

The sum of \(n+m\) over all subproblems is bounded by \(2N\). Therefore, it suffices to solve each subproblem in \(\tilde{O}(n+m)\) time.

If we construct the bipartite graph appearing in the subproblem as is, we would have \(\mathrm{O}(N)\) edges and run out of time, so consider reducing the edges. Specifically, by deleting edges according to the following procedure, the number of edges becomes \(\mathrm{O}(n)\). (We omit the detailed proof of correctness, but it can be proved with the approach “matchings using deleted edges can be replaced with edges that were not deleted without becoming worse”.)

  • First, among edges with the same pair of endpoints, keep only the edge with the smallest weight and delete all other edges.
  • Then, for each left vertex \(i\), keep up to four edges extending from \(i\) with the smallest weights, and delete the rest.

Once we actually reduce the number of edges to \(\mathrm{O}(n)\), the subproblem can be solved in \(\mathrm{O}((n+m) \log (n+m))\) using a minimum cost flow algorithm.

By the above discussion, the current problem has been reduced to performing the following process for \(k=1,2,\dots,N\).

Consider trees \(T, U\) as rooted trees with vertex \(k\) as the root.
Let \(b_1, b_2, \dots, b_n\) be the children of vertex \(k\) in tree \(T\).
Let \(c_1, c_2, \dots, c_m\) be the children of vertex \(k\) in tree \(U\).
For \(i = 1, 2, \dots, n\), extract up to four vertices \(v\) in the subtree of \(b_i\) in \(T\) with the smallest \(A_v\). However, if vertices \(v_1, v_2\) both belong to the subtree of \(c_j\) in \(U\), they cannot be extracted simultaneously.

Let us change the perspective slightly to make the above process easier to handle with data structures.

Consider trees \(T, U\) as rooted trees with vertex \(k\) as the root.
Let \(b_1, b_2, \dots, b_n\) be the children of vertex \(k\) in tree \(T\).
Let \(c_1, c_2, \dots, c_m\) be the children of vertex \(k\) in tree \(U\).
First, for \(v=1,2,\dots,N\), if vertex \(v\) belongs to the subtree of \(c_j\) in tree \(U\), color vertex \(v\) in tree \(T\) with color \(j\).
Then, for \(i = 1, 2, \dots, n\), extract up to four vertices \(v\) in the subtree of \(b_i\) in \(T\) with the smallest \(A_v\). However, vertices of the same color can be chosen at most once.

With this reformulation, we can see that the query for each \(i\) can be processed with Euler tour + segment tree. That is, merging “data holding up to four vertices of different colors” can be done quickly, so it can be put on a segment tree.

The issue is the operation of coloring each vertex, which currently requires coloring \(\mathrm{O}(N^2)\) times, so if we can process this part with fewer recolorings, we can solve the problem. In other words, it suffices to solve the following problem.

Initially, all vertices are colored with color \(0\).
Using \(\mathrm{o}(N^2)\) recoloring operations, make the following state appear for \(k=1,2,\dots,N\) (in any order).

  • Consider tree \(U\) as a rooted tree with vertex \(k\) as the root.
    Let \(c_1, c_2, \dots, c_m\) be the children of vertex \(k\) in tree \(U\).
    For the subtree of each \(c_j\), the colors painted on vertices in the subtree are the same, and colors of vertices in different subtrees differ.

This problem can be solved with \(\mathrm{O}(N \log N)\) recolorings using the structure of heavy-light decomposition. (It can also be viewed as a variant of the algorithm called DSU on Tree.)

Consider tree \(U\) as a rooted tree with vertex \(1\) as the root. Let \(d_1, d_2, \dots, d_l\) be the children of vertex \(k\), and let \(d_1\) be the heavy child. The state we want to produce satisfies the following conditions:

  • The subtree of \(d_i\) is colored with color \(i\)
  • Other vertices, that is, vertices reachable via the edge toward the parent of \(k\), are colored with color \(0\)

This can be achieved by performing DFS with the following procedure.

def dfs(k, keep):
  for c in (light child of k):
    dfs(c, 0)
  if k is not leaf:
    dfs(d_1, 1)  # heavy child
  for i = 2 to (the number of children of k):
    paint descendants of d_i with color i
  process the k-th query
  if keep == 0:
    paint descendants of k with color 0
  else:
    paint vertex k with 1
    for c in (light child of k):
      paint descendants of c with color 1

Each vertex \(v\) is recolored on the order of the number of light edges existing in the direction of its ancestors, so the total number of recolorings is suppressed to \(\mathrm{O}(N \log N)\). Therefore, considering that the segment tree data is updated for each recoloring, the time complexity of this part is \(\mathrm{O}(N \log^2 N)\).

By implementing all of the above algorithms appropriately, we can solve the problem. The time complexity is \(\mathrm{O}(N \log^2 N)\), which is sufficiently small.

投稿日時:
最終更新: