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