375. query on a treeproblem code: qtree |
You are given a tree (an acyclic undirected connected graph)NNodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
- Change I Ti: Change the cost of the I-th edge to Ti
Or
- Query A B: Ask for the maximum edge cost on the path from node A to Node B
Input
The first line of input contains an integerT, The number of test cases (T<= 20). T test cases follow.
For each test case:
- In the first line there is an integerN(N<= 10000 ),
- In the nextN-1 lines, the I-th line describes the I-th edge: a line with three IntegersA B CDenotes an edgeA,BOf costC(C<= 1000000 ),
- The next lines contain instructions"Change I ti"Or"Query a B",
- The end of each test case is signiied by the string"Done".
There is one blank line between successive tests.
Output
For each"Query"Operation, write one integer representing its result.
Example
Input:131 2 12 3 2QUERY 1 2CHANGE 1 3QUERY 1 2DONEOutput:13
Question:
Give you a tree. Then you can perform two operations on the tree.
1. Modify the edge weight of an edge.
2. query the U-> V path. Maximum Edge Weight.
Click the link to open the question
Ideas:
Before learning the tree Chain Division, I felt that this algorithm was difficult. I learned it and found it was not as difficult as I thought.
For more information, see click to open the link.
# Include <algorithm> # include <iostream> # include <string. h> # include <stdio. h> using namespace STD; const int INF = 0x3f3f3f3f; const int maxn = 10010; typedef long ll; # define lson L, mid, ls # define rson Mid + 1, R, rsint Fa [maxn], DEP [maxn], SZ [maxn], son [maxn], Id [maxn], top [maxn], CNT, PTR; // note that SZ [u] indicates the number of nodes in the subtree rooted in U, and Dep [u] indicates the depth of U (the root depth is 1 ), top [u] indicates the top node of the heavy chain where u is located, // Fa [u] indicates U's father, son [u] indicates the son node of U on the same heavy chain as U (also known as heavy son), Id [u] indicates the edge connecting u and its Father's Day (Gu The location in the online segment tree. Struct node {int V; node * Next;} ed [maxn <1], * head [maxn]; int MAV [maxn <2], UU [maxn], VV [maxn], wei [maxn]; void build (int l, int R, int RT) {MAV [RT] =-INF; If (L = r) return; int ls = RT <1, RS = ls | 1, mid = (L + r)> 1; build (lson); Build (rson );} void Update (int l, int R, int RT, int P, int d) {If (L = r) {MAV [RT] = D; return ;} int ls = RT <1, RS = ls | 1, mid = (L + r)> 1; if (P <= mid) Update (lson, P, d); else Update (rson, P, d); MAV [RT] = max (MAV [ls], Mav [RS]);} int Qu (int l, int R, int RT, int L, int R) {If (L <= L & R <= r) return MAV [RT]; int ls = RT <1, RS = ls | 1, mid = (L + r)> 1, TP =-INF; If (L <= mid) TP = max (TP, Qu (lson, L, R )); if (r> mid) TP = max (TP, Qu (rson, L, R); Return TP;} void Adde (int u, int V) {ed [CNT]. V = V; Ed [CNT]. next = head [u]; head [u] = & ED [CNT ++];} void DFS (int u) {int V, MS =-INF; SZ [u] = 1, son [u] =-1; for (node * P = head [u]; P! = NULL; P = p-> next) {v = p-> V; If (V = Fa [u]) continue; Fa [v] = u; dep [v] = Dep [u] + 1; DFS (V); If (SZ [v]> MS) MS = SZ [v], son [u] = V; SZ [u] + = SZ [v] ;}} void GETID (int u, int ft) {ID [u] =++ PTR, top [u] = ft; if (son [u]! =-1) GETID (son [u], top [u]); For (node * P = head [u]; P! = NULL; P = p-> next) {If (p-> V = Fa [u] | p-> V = Son [u]) continue; GETID (p-> V, p-> V) ;}} void Init (int rt) {Fa [RT] =-1; Dep [RT] = PTR = 0; DFS (RT); GETID (RT, RT); // The root has no parent edge. However, the online segment tree occupies 1 position. But it is not used. It is easy to write build (1, PTR, 1); // 1-ptr. PTR edge. Is the virtual edge of the root .} Inline int calc (int u, int v) {int F1 = top [u], f2 = top [v], TP =-INF; while (F1! = F2) {If (DEP [F1] <Dep [F2]) Swap (F1, F2), swap (u, v); TP = max (TP, Qu (1, PTR, 1, Id [F1], Id [u]); U = Fa [F1], F1 = top [u]; // start to write Fa [F1] As Fa [u]. T early in the morning... Ah...} If (u = V) return TP; If (DEP [u]> Dep [v]) Swap (u, v); TP = max (TP, Qu (1, PTR, 1, Id [son [u], Id [v]); Return TP;} int main () {int N, U, V, W, T, RT, I; char cmd [100]; scanf ("% d", & T); While (t --) {scanf ("% d", & N ); RT = (n + 1)/2; CNT = 0; memset (Head, 0, sizeof head); for (I = 1; I <n; I ++) {scanf ("% d", & U, & V, & W); UU [I] = u, VV [I] = V, wei [I] = W; Adde (u, v); Adde (v, U);} Init (RT); for (I = 1; I <N; I ++) {If (DEP [UU [I]> Dep [VV [I]) Swap (uu [I], VV [I]); Update (1, PTR, 1, Id [VV [I], wei [I]);} while (1) {scanf ("% s", CMD ); if (CMD [0] = 'D') break; scanf ("% d", & U, & V ); if (CMD [0] = 'C') Update (1, PTR, 1, Id [VV [u], V ); else printf ("% d \ n", Calc (u, v) ;}} return 0 ;}
Spoj query on a tree (tree link partitioning template)