Question:
For a tree, each side of the tree has a color, black or white. At first, all sides are black and there are two operations:
Operation 1: Turn the I side into white or black.
Operation 2: Ask U and V for the shortest path only after black.
Tree link splitting + tree Array
Learning tree link partitioning:
/* Tree link partitioning: divides the weight chain and turns a tree into consecutive segments. Edge Weight record up */# include <iostream> # include <cstdio> # include <cstring> # include <cmath> using namespace STD; const int max = 111111; // Number of knots in the subtree, chainte of the link, same-link son, node depth, node location in the interval, parent node int siz [Max], top [Max], son [Max], DEP [Max], W [Max], Fa [Max]; // record a tree struct edge {int V, NE, ID;} edge [max <1]; int head [Max], CNT, num; int vis [Max], POS [Max]; // first DFS, extract basic information and divide the weight chain void dfs1 (int u, int v) {Fa [v] = u, DEP [v] = Dep [u] + 1; Siz [v] = 1; vis [v] = 1; int TEM = 0, P =-1; for (INT I = head [v]; I! = 0; I = edge [I]. Ne) {int KID = edge [I]. V; If (! Vis [Kid]) {dfs1 (v, kid); siz [u] + = siz [Kid]; If (TEM <siz [Kid]) TEM = siz [Kid], P = kid ;}} son [v] = P;} // For the second DFS, relink to the void dfs2 (int h, int V) {top [v] = H; W [v] = ++ num; vis [v] = 1; if (son [v]! =-1) dfs2 (H, son [v]); For (INT I = head [v]; I! = 0; I = edge [I]. Ne) {int KID = edge [I]. V; If (son [v]! = Kid &&! Vis [Kid]) dfs2 (Kid, kid); POS [edge [I]. id] = W [Kid]; // edge ing to the next node} void Adde (int u, int V, int num) {edge [++ CNT]. V = V, edge [CNT]. id = num; edge [CNT]. ne = head [u], head [u] = CNT;} int A [Max]; // POS is the edge's new number void add (int x, int K) {for (; x <= num; x + = x &-x) A [x] + = K;} int getsum (int x) {int S = 0; for (; x> 0; X-= x &-x) S + = A [X]; return s;} void modify (int x, int K) {x = POS [X]; int sta = G Etsum (x)-getsum (X-1); If (STA = k) return; else add (x, K-Sta);} void query (int u, int v) {int S = 0, F1 = top [u], f2 = top [v], Len = 0; while (F1! = F2) {If (DEP [F1] <Dep [F2]) {int y = W [v], x = W [F2]; If (F2! = V) {If (S + = getsum (y)-getsum (x) break; V = F2; Len + = Y-X ;} if (S + = getsum (x)-getsum (X-1) break; V = Fa [v], f2 = top [v]; Len ++ ;} else {int y = W [u], x = W [F1]; If (F1! = U) {If (S + = getsum (y)-getsum (x) break; u = F1; Len + = Y-X ;} if (S + = getsum (x)-getsum (X-1) break; u = Fa [u], F1 = top [u]; Len ++ ;}} int y = W [v], x = W [u]; S + = getsum (max (Y, x)-getsum (min (Y, x )); len + = ABS (Y-x); printf ("% d \ n", S = 0? Len:-1);} int N, U, V, M, T; int main () {scanf ("% d", & N ); for (INT I = 1; I <n; I ++) {scanf ("% d", & U, & V); Adde (u, v, i), Adde (v, U, I);} dfs1 (0, 1); memset (VIS, 0, sizeof vis); dfs2 (1, 1 ); scanf ("% d", & M); int K, L, R, Tol = 0; For (INT I = 1; I <= m; I ++) {scanf ("% d", & K); If (K! = 3) {scanf ("% d", & T); Modify (T, K = 1? 0: 1) ;}if (k = 3) {scanf ("% d", & L, & R); query (L, R );}}}
View code
Codeforces 165d. Beard graph solution report