Description
Given a tree of n points, the Edge has edge rights. The following actions are required:
DIST a B The sum of Benquan on the path from point A to point B
KTH a B K inquiry point A to point B the number of the K-point on the direction path
There are several sets of test data, each set of data ending with done.
Input
The first set of data contains an integer \ (t\)that represents the test data for the \ (t\) Group. \ (1\leq T \leq 25\)
For each set of test data:
- First line an integer \ (n (n \leq 10000) \)
- Next there is a \ (n-1\) line, each line describes an edge on the tree (A,b,c (c\leq 100000) \)
- The next few lines of operations include \ (DIST \ a \ b\),\ (KTH \ a \ b \ k\)
- End with \ (done\)
Output
For each \ (dist\) and \ (kth\) , ask for an output line.
It is obvious that LCA, but the difficulty is how to find the answer to the kth\ .
There are two things first.
One.\ (k \leq depth[a]-depth[lca_{x,y}]+1\)
Obviously, at this point \ (k\) is necessarily on the path of \ (x->lca_{x,y}\) , we only need to know its depth can be doubled to be obtained.
Can be obtained in depth of \ (depth[a]-k+1\)
Two.\ (k > depth[a]-depth[lca_{x,y}]+1\)
At this point, k\ points must exist on the path of \ (y->lca_{x,y}\) , but how to find the depth is a problem.
First set \ (ans\) is the depth of the first (k\) point.
The information we can get is \ (k\) must be in \ (y->lca_{x,y}\),
So the new depth must be at least \ (k (depth[x]-depth[lca_{x,y}]+1) \)
But because our \ (lca_{x,y}\) is not necessarily \ (1\)(here I take \ (1\) as Root)
So the original formula also needs to add a \ (depth[lca_{x,y}]\).
So you can get a formula like this.
\[ans=k-depth[x]+2*depth[lca_{x,y}]-1;\]
Once you know the depth, multiply the jump directly.
代码
#include <cstdio> #include <cctype> #include <cstring> #include <algorithm> #define CLEAR (a) memset (a,0,sizeof a) #define N 10008#define R registerusing namespace std;inline void in (int &x) {int F=1;x=0;char s =getchar (); while (!isdigit (s)) {if (s== '-') F=-1;s=getchar ();} while (IsDigit (s)) {x=x*10+s-' 0 '; S=getchar ();} X*=f;} int t;int n,head[n],tot;struct cod{int u,v,w;} edge[n<<2];inline void Add (int x,int y,int z) {edge[++tot].u=head[x]; Edge[tot].v=y; Edge[tot].w=z; Head[x]=tot;} int depth[n],f[n][21],dis[n];void dfs (int u,int fa,int dist) {f[u][0]=fa;dis[u]=dis[fa]+dist;depth[u]=depth[fa]+1; for (R int i=1; (1<<i) <=depth[u];i++) f[u][i]=f[f[u][i-1]][i-1]; for (R int i=head[u];i;i=edge[i].u) {if (EDGE[I].V==FA) continue; DFS (EDGE[I].V,U,EDGE[I].W); }}inline int LCA (int x,int y) {if (Depth[x]>depth[y]) swap (x, y); for (R int i=17;i>=0;i--) if (depth[x]+ (1<<i) <=depth[y])Y=f[y][i]; if (x==y) return y; for (R int i=17;i>=0;i--) {if (f[x][i]==f[y][i]) continue; X=f[x][i],y=f[y][i]; } return f[x][0];} char s[108];inline int query (int x,int y,int k) {R int la=lca (x, y); if (depth[x]-depth[la]+1>=k) {R int ans=depth[x]-k+1; for (R int i=17;i>=0;i--) {if (depth[x]-ans>= (1<<i)) x=f[x][i]; } return x; } else {R int ans=depth[la]*2+k-depth[x]-1; for (R int i=17;i>=0;i--) if ((1<<i) <=depth[y]-ans) y=f[y][i]; return y; }}int Main () {in (T); for (; T t--) {in (n); Tot=0;clear (head), Clear (DIS), clear (f); Clear (depth); for (R int i=1,x,y,z;i<n;i++) {in (x), in (Y), in (z); Add (x, y, z); add (y,x,z); } dfs (1,0,0); for (R int x,y,la,k;;) {scanf ("%s", s+1); if (s[2]== ' O ') break; if (s[2]==' I ') {in (x), in (y); La=lca (x, y); printf ("%d\n", Dis[x]+dis[y]-2*dis[la]); } else {in (x), in (Y), in (k); printf ("%d\n", Query (X,y,k)); } } }}
LCA "SP913" qtree-query on a tree II