You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length.
We will ask you to perfrom some instructions of the following form:
- DIST a b : ask for the distance between node a and node b
or - KTH a b k : ask for the k-th node on the path from node a to node b
Example:
N = 6
1 2 1 // edge connects node 1 and node 2 has cost 1
2 4 1
2 5 2
1 3 1
3 6 2
Path from node 4 to node 6 is 4 -> 2 -> 1 -> 3 -> 6
DIST 4 6 : answer is 5 (1 + 1 + 1 + 2 = 5)
KTH 4 6 4 : answer is 3 (the 4-th node on the path from node 4 to node 6 is 3)
Input
The first line of input contains an integer t, the number of test cases (t <= 25). ttest cases follow.
For each test case:
- In the first line there is an integer N (N <= 10000)
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 100000)
- The next lines contain instructions "DIST a b" or "KTH a b k"
- The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "DIST" or "KTH" operation, write one integer representing its result.
Print one blank line after each test.
Example
Input: 1 6 1 2 1 2 4 1 2 5 2 1 3 1 3 6 2 DIST 4 6 KTH 4 6 4 DONE Output: 5 3
ideas:
Multiply naked questions. . . Set of boards,
you need to deal with it when you ask for the kth one, and nothing else. , .
Implementation code:
#include<bits/stdc++.h> using namespace std; #define ll long long const int M = 2e5+10; int dist[M],p[M][30],dep[M],head[M]; int cnt1,n; struct node{ int to,next,w; }e[M]; void add(int u,int v,int w){ e[++cnt1].w=w;e[cnt1].to=v;e[cnt1].next=head[u];head[u]=cnt1; e[++cnt1].w=w;e[cnt1].to=u;e[cnt1].next=head[v];head[v]=cnt1; } void dfs(int u){ for(int i = head[u];i != -1;i=e[i].next){ int v = e[i].to; if(v == p[u][0]) continue; dep[v] = dep[u] + 1 ; dist[v] = dist[u] + e[i].w; p[v][ 0 ] = u; // p[i][0] stores i's parent node dfs(v); } } void init(){ for(int j = 1;(1<<j)<=n;j++){ for(int i = 1;i <= n;i++){ p[i][j] = p[p[i][j-1]][j-1]; //cout<<i<<" "<<j<<" "<< p[i][j]<<endl; } } } int lca( int a, int b){ if (dep[a] > dep[b]) swap(a,b); int h = dep[b] - dep[a]; // h is the height difference for ( int i = 0 ;( 1 <<i)<=h;i++){ // (1<<i)&f find the position where h is converted to binary 1 and move to the corresponding position if (( 1 << i)&h) b = p[b][i]; // such as h = 5(101), first move 2^0 ancestors, then move 2^2 ancestors } // cout<<a<<" "< <b<<endl; if (a!= b){ for ( int i = 22 ;i >= 0;i -- ){ if (p[a][i]!=p[b][i]){ // Start from the largest ancestor, judge whether a and b ancestors are the same a = p[a][i] ; b = p[b][i]; // If not the same, a,b, move up 2^j at the same time } } a = p[a][ 0 ]; // The father of a is LCA } return a; } int kth(int u,int k){ for(int i = 0;i < 22;i ++) if(k >> i&1) u = p[u][i]; return u; } intmain () { int t,u,v,w,k; scanf("%d",&t); while(t--){ scanf("%d",&n); cnt1 = 0; //init(); memset(head,-1,sizeof(head)); for(int i = 0;i < n-1;i ++){ scanf("%d%d%d",&u,&v,&w); add(u,v,w); } dfs(1); init(); char s[10]; while(scanf("%s",s)!=EOF){ if(s[1]=='O') break; scanf("%d%d",&u,&v); int num = lca(u,v); if(s[1]=='I'){ printf("%d\n",dist[u]+dist[v]-2*dist[num]); } if(s[1]=='T'){ scanf("%d",&k); int x = dep[u] - dep[num]; if(x + 1 >= k) printf("%d\n",kth(u,k-1)); else printf("%d\n",kth(v,dep[v]+dep[u]-2*dep[num]+1-k)); } } } return 0; }