You were given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3 ... N-1.
The first line of input contains an integer T, the number of test cases (T <= 20). T test cases follow.
There is one blank line between successive tests.
For each "QUERY" operation, the write one integer representing its result.
Input:131 2 3 2QUERY 1 2CHANGE 1 3QUERY 1 2DONEOutput:13
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <queue> #include <iostre Am> #define MAX (A, B) (A>B?A:B) using namespace std; int head[50050],cnt,vis[50050]; struct S {int u,v,w,next; }edge[50050<<1]; struct LCT {int bef[50050],pre[50050],next[50050][2],key[50050],val[50050],belong[50050]; void Init () {memset (pre,0,sizeof (pre)); memset (Next,0,sizeof (next)); } void Pushup (int x) {Val[x]=max (Key[x],max (val[next[x][1]],val[next[x][0])); } void rotate (int x,int kind) {int y,z; Y=PRE[X]; Z=pre[y]; Next[y][!kind]=next[x][kind]; Pre[next[x][kind]]=y; Next[z][next[z][1]==y]=x; Pre[x]=z; Next[x][kind]=y; Pre[y]=x; Pushup (y); } void Splay (int x) {int rt; for (Rt=x;pre[rt];rt=pre[rt]); if (X!=RT) {BEF[X]=BEF[RT]; bef[rt]=0; while (Pre[x]) {if (next[pre[x]][0]==x) {Rotat E (x,1); } else rotate (x,0); } pushup (x); }} void access (int x) {int fa; for (Fa=0;x;x=bef[x]) {splay (x); pre[next[x][1]]=0; Bef[next[x][1]]=x; NEXT[X][1]=FA; Pre[fa]=x; bef[fa]=0; Fa=x; Pushup (x); }} void Change (int x,int val) {int t; T=BELONG[X-1]; Key[t]=val; Splay (t); } int query (int x,int y) {access (Y); for (Y=0;x;x=bef[x]) {splay (x); if (!bef[x]) Return Max (val[y],val[next[x][1]); pre[next[x][1]]=0; Bef[next[x][1]]=x; Next[x][1]=y; Pre[y]=x; bef[y]=0; Y=x; Pushup (x); }}}LCT; void Add (int u,int v,int W) {edge[cnt].u=u; Edge[cnt].v=v; Edge[cnt].w=w; Edge[cnt].next=head[u]; head[u]=cnt++; } void BFs (int u) {int i,y; queue<int>q; memset (vis,0,sizeof (VIS)); Vis[u]=1; Q.push (U); while (!q.empty ()) {U=q.front (); Q.pop (); for (int i=head[u];i!=-1;i=edge[i].next) {int v=edge[i].v; if (!vis[v]) {lct.bef[v]=u; LCT.KEY[V]=LCT.VAL[V]=EDGE[I].W; lct.belong[i>>1]=v; Vis[v]=1; Q.push (v); }}}} int main () {int t;scanf ("%d", &t), while (t--) {int N;memset (head,-1,sizeof (head)); Cnt=0;int I;char s[10];scanf ("%d", &n); for (i=1;i<n;i++) {int a,b,c;scanf ("%d%d%d", &a,&b,&c); Add (a,b,c); add (b,a,c);} Lct.init (); BFS (1); while (scanf ("%s", s)!=eof) {int a,b;if (strcmp (S, "done") ==0) break;scanf ("%d%d", &a,&b); if (s[0]== ' Q ') {printf ("%d\n", Lct.query (A, b));} Elselct.change (A, b);}}}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Spoj topic 375 Query on a tree (link cut tree edge Update, ask for two points maximum)