375. Query on a treeProblem code: QTREE |
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
树链剖分第一题。
我觉得树链剖分就是lca+线段树,只是引入了重链等新的概念。因此,学树链剖分前把线段树学好,树链剖分就十分简单了!
#include <iostream> #include <cstring> #include <algorithm> #include <cstdlib> #include <cstdio> #include <vector> #define N 10005 #define pb push_back using namespace std; int n,T,num,id[N],siz[N],dep[N],top[N],fa[N],son[N],val[N]; vector<int> v[N]; struct edge { int x,y,v; }e[N*3]; struct segtree { int l,r,ma; }a[N*3]; void dfs1(int x,int f,int de) //第一次dfs,得到depth,size,son,fa { dep[x]=de; siz[x]=1; son[x]=0; fa[x]=f; for (int i=0;i<v[x].size();i++) if (v[x][i]!=fa[x]) { int u=v[x][i]; dfs1(u,x,de+1); siz[x]+=siz[u]; if (siz[son[x]]<siz[u]) son[x]=u; } } void dfs2(int x,int tp) //第二次dfs,得到每个点所在重链的深度最小点top[x] { top[x]=tp; id[x]=++num; if (son[x]) dfs2(son[x],tp); for (int i=0;i<v[x].size();i++) { int u=v[x][i]; if (u==fa[x]||u==son[x]) continue; dfs2(u,u); } } void push_up(int x) { a[x].ma=max(a[x<<1].ma,a[x<<1|1].ma); } void build(int x,int l,int r) { a[x].l=l,a[x].r=r; if (l==r) { a[x].ma=val[l]; return; } int m=(l+r)>>1; build(x<<1,l,m); build(x<<1|1,m+1,r); push_up(x); } void update(int x,int p,int c) //修改操作 { if (a[x].l==a[x].r) { a[x].ma=c; return; } int m=(a[x].l+a[x].r)>>1; if (p<=m) update(x<<1,p,c); else update(x<<1|1,p,c); push_up(x); } int getmax(int x,int l,int r) { if (a[x].l>=l&&a[x].r<=r) return a[x].ma; int m=(a[x].l+a[x].r)>>1; int ans=0; if (l<=m) ans=getmax(x<<1,l,r); if (r>m) ans=max(ans,getmax(x<<1|1,l,r)); return ans; } int query(int u,int v) { int tp1=top[u],tp2=top[v]; int ans=-1; while (tp1!=tp2) { if (dep[tp1]<dep[tp2]) swap(tp1,tp2),swap(u,v); ans=max(getmax(1,id[tp1],id[u]),ans); u=fa[tp1]; tp1=top[u]; } if (u==v) return ans; if (dep[u]>dep[v]) swap(u,v); ans=max(ans,getmax(1,id[son[u]],id[v])); return ans; } void clea() //多组数据 { for (int i=1;i<=n;i++) v[i].clear(); } int main() { scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<n;i++) { scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v); v[e[i].x].pb(e[i].y); v[e[i].y].pb(e[i].x); } num=0; dfs1(1,0,1); dfs2(1,1); for (int i=1;i<n;i++) { if (dep[e[i].x]<dep[e[i].y]) swap(e[i].x,e[i].y); val[id[e[i].x]]=e[i].v; } build(1,1,num); char s[20]; while (scanf("%s",s)!=EOF) { if (s[0]=='D') break; int x,y; scanf("%d%d",&x,&y); if (s[0]=='C') update(1,id[e[x].x],y); else printf("%d\n",query(x,y)); } clea(); } return 0; }
【树链剖分模板】【SPOJ 375】 Query on a tree
原文地址:http://blog.csdn.net/regina8023/article/details/41742787