C - Tree and LCS Editorial by evima
[1] Constructing a solution
You can always construct a permutation with the similarity of \(1\). We will first present an algorithm to construct it and then show that its similarity is \(1\).
Algorithm
Step 0. Prepare a sequence \(P\) of length \(N\) whose elements are undecided.
Step 1. Insert all leaves of the tree into a queue.
Step 2. Repeat the following as long as the queue has two or more vertices.
- Remove two vertices from the queue (let \(u\) and \(v\) be the removed vertices). Let \(P_u= v\) and \(P_v=u\). Remove the vertices \(u\) and \(v\) from the tree \(T\). If there are leaves after this removal, put all of them into the queue.
Step 3. After Step 2, the queue contains one vertex \(x\) only if \(N\) is odd. Let \(P_x=x\).
Proof of the validness
First, the above algorithm assigns each of \(1,2,\ldots,N\) to \(P\) exactly once, so \(P\) is indeed a permutation.
Next, let us prove by induction that the similarity of \(P\) is \(1\).
For \(N=1,2\), the algorithm constructs a permutation with the similarity of \(1\).
Consider the case \(N\geq 3\). Let \(a\) and \(b\) be the first two vertices removed in Step 2. From the assignment of \(a\) and \(b\) to \(P\), there is no path for which a longest common subsequence contains both \(a\) and \(b\). If a common subsequence contains \(a\), it follows from the assignment that such a subsequence has a length of \(1\). The same goes for \(b\).
From this, we get a problem whose size is reduced by \(2\). Repeat this to complete the proof.
[2] Sample implementation
Python: (using a stack instead of a queue)
n = int(input())
g = [[] for _ in range(n)]
for _ in range(n - 1):
u, v = map(int, input().split())
u -= 1
v -= 1
g[u].append(v)
g[v].append(u)
deg, p = [0] * n, [0] * n
st = []
for i in range(n):
deg[i] = len(g[i])
if deg[i] == 1:
st.append(i)
while len(st) >= 2:
u = st.pop()
v = st.pop()
p[u], p[v] = v, u
for to in g[u]:
deg[to] -= 1
if deg[to] == 1:
st.append(to)
for to in g[v]:
deg[to] -= 1
if deg[to] == 1:
st.append(to)
if len(st):
x = st.pop()
p[x] = x
p = [v + 1 for v in p]
print(*p)
[3] Bonus
Write a code that judges solutions in \(\mathrm{O}(N^2)\). (Equivalent to ABC-E or F?)
posted:
last update: