Question:
Given a tree and M queries, each query requires the minimum number of points in the path not formed by the U and V vertices.
Ideas:
In the beginning, we thought it was a LCA... But t several times... Later, we found that we could do it without using LCA.
Consider every question u and v. If their LCA is not 1, then 1 must be the answer. However, if the LCA is T, we only need to dye the node when traversing the tree. The color is 1. son color if X is in the Child tree of Y (Y is the son of 1) then his color is Y.
After coloring, we consider how the answer is made up.
The answer is the minimum value of the node in the red-blue-green subtree. We only need to separate the three parts to solve the problem.
Define f [u] [x] to indicate the node number X in the Child tree rooted in U. This can be solved through the tree DP. With this, the green and red parts can be solved.
Defining G [u] indicates the minimum node number of the Child tree on the side of the path above the U node to 1. That is, the blue part in the figure can also be solved by using F for tree DP.
Note:
The reason why the blue part does not contain the green part or the green part in the red part is that one of the u and v nodes may be 1.
As I wrote that DFS hangdian will blow up the stack, I remember to add the stack and submit it with C ++.
Code:
# Pragma comment (linker, "/Stack: 102400000,102400000") # include <cstdio> # include <cstring> # include <algorithm> using namespace STD; # define n Limit 10int f [N] [4], G [N], Col [N], head [N]; int n, m, color, TOT, ans; struct edge {int V, next;} ed [N * 2]; int D (int A, int B) {if (a <B) return a; return B ;} void add (int u, int v) {ed [tot]. V = V; Ed [tot]. next = head [u]; head [u] = tot ++;} void dfs1 (int u, int FA ){ Int I, V; If (u! = 1) COL [u] = color; for (I = head [u]; ~ I; I = ed [I]. Next) {v = ed [I]. V; If (u = 1) color = V; If (V! = FA) {dfs1 (v, U); F [u] [3] = d (v, F [v] [0]); sort (F [u], f [u] + 4) ;}} void dfs2 (int u, int FA) {If (Fa! = 1) {If (d (u, F [u] [0])! = F [fa] [0]) g [u] = f [fa] [0]; else G [u] = f [fa] [1]; if (G [u]> G [fa]) g [u] = G [fa];} int I, V; for (I = head [u]; ~ I; I = ed [I]. Next) {v = ed [I]. V; If (V! = FA) dfs2 (v, u) ;}} int main () {int I, j, U, V; while (~ Scanf ("% d", & N, & M) {for (I = 1; I <= N; I ++) {f [I] [0] = f [I] [1] = f [I] [2] = f [I] [3] = G [I] = N; head [I] =-1;} Col [1] = 1; Tot = ans = 0; for (I = 1; I <n; I ++) {scanf ("% d", & U, & V); add (u, v); add (v, U);} dfs1 (1, 1 ); dfs2 (1, 1); for (I = 1; I <= m; I ++) {scanf ("% d", & U, & V ); U ^ = ans; V ^ = ans; If (COL [u] = Col [v]) {If (u = 1 | V = 1) ans = 2; else ans = 1;} else {If (u> V) Swap (u, v); ans = min (F [v] [0], min (G [u], G [v]); If (u! = 1) {ans = min (ANS, F [u] [0]); V = min (COL [v], F [col [v] [0]); U = min (COL [u], F [col [u] [0]); For (j = 0; j <3; j ++) {If (F [1] [J]! = U & F [1] [J]! = V) {ans = min (ANS, F [1] [J]); break ;}} else {v = min (COL [v], f [col [v] [0]); For (j = 0; j <3; j ++) {If (F [1] [J]! = V) {ans = min (ANS, F [1] [J]); break ;}}} printf ("% d \ n", ANS );}} return 0 ;}