标签:
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
题解:
抄板子
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include<iostream> using namespace std ; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back #define fi first #define se second #define MP make_pair typedef long long ll; const int maxn = 100010; const int inf = 0x3f3f3f3f; const int mod = 1000000007; struct sss { int to,next; }edge[maxn >> 1]; int head[maxn],tot; int top[maxn];//top[v]表示v所在的重链的顶端节点 int fa[maxn]; //父亲节点 int deep[maxn];//深度 int num[maxn];//num[v]表示以v为根的子树的节点数 int p[maxn];//p[v]表示v与其父亲节点的连边在线段树中的位置 int fp[maxn];//和p数组相反 int son[maxn];//重儿子 int pos; void init() { mem(head);tot=1;mem(son); pos=1; } void add(int u,int v) { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } void dfs1(int u,int pre,int d) {///第一遍dfs求出fa,deep,num,son deep[u]=d; fa[u]=pre; num[u]=1; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(v != pre) { dfs1(v,u,d+1); num[u] += num[v]; if(son[u] == 0 || num[v] > num[son[u]]) son[u]=v; } } } void dfs2(int u,int sp) {/////第二遍dfs求出top和p top[u]=sp; if(son[u] != 0) { p[u] = pos++; fp[p[u]] = u; dfs2(son[u],sp); } else { p[u] = pos++; fp[p[u]] = u; return ; } for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(v != son[u] && v != fa[u]) { dfs2(v,v); } } } ////线段树 struct ss{ int l,r; int M; }tr[maxn >> 2]; void build(int k,int s,int t) { tr[k].l=s;tr[k].r=t; tr[k].M=0; if(s==t) return ; int mid = (s+t) >> 1; build(k<<1,s,mid); build(k<<1|1,mid+1,t); } void pushup(int k) { tr[k].M=max(tr[k<<1].M,tr[k<<1|1].M); } void update(int k,int x,int c) { if(tr[k].l==x&&tr[k].r==x) { tr[k].M=c; return ; } int mid = (tr[k].l+tr[k].r) >> 1; if(x<=mid) update(k<<1,x,c); else update(k<<1|1,x,c); pushup(k); } int ask(int k,int s,int t) { if(tr[k].l==s&&tr[k].r==t) { return tr[k].M; } int mid = (tr[k].l+tr[k].r) >> 1; if(t<=mid) return ask(k<<1,s,t); else if(s>mid) return ask(k<<1|1,s,t); else return max(ask(k<<1,s,mid),ask(k<<1|1,mid+1,t)); } int finds(int u,int v) { int fx = top[u],fy = top[v]; int tmp=0; while(fx!=fy) { if(deep[fx] < deep[fy]) { swap(fx,fy); swap(u,v); } tmp = max(tmp,ask(1,p[fx],p[u])); u = fa[fx]; fx = top[u]; } if(u==v) return tmp; if(deep[u] > deep[v]) swap(u,v); return max(tmp,ask(1,p[son[u]],p[v])); } int main() { int T,e[maxn][3],n; scanf("%d",&T); while(T--) { init(); scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]); add(e[i][0],e[i][1]);add(e[i][1],e[i][0]); } dfs1(1,0,0);// dfs2(1,1);// build(1,1,pos-1); for(int i=1;i<n;i++) { if(deep[e[i][0]] > deep[e[i][1]]) swap(e[i][0],e[i][1]); update(1,p[e[i][1]],e[i][2]); } char ch[10]; int u,v; while(~scanf("%s",ch)) { if(ch[0]==‘D‘) break; scanf("%d%d",&u,&v); if(ch[0]==‘Q‘) printf("%d\n",finds(u,v)); else update(1,p[e[u][1]],v); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/zxhl/p/5223226.html