• Query on a tree II 倍增LCA


    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). t test 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
    
    看到树上两点距离很容易想到LCA,
    对于第K个点我们同样可以倍增解决;
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<time.h>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    //#include<cctype>
    //#pragma GCC optimize(2)
    using namespace std;
    #define maxn 200005
    #define inf 0x7fffffff
    //#define INF 1e18
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    #define mclr(x,a) memset((x),a,sizeof(x))
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 9999973;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-5
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    //const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    typedef pair<int, int> pii;
    
    inline int rd() {
    	int x = 0;
    	char c = getchar();
    	bool f = false;
    	while (!isdigit(c)) {
    		if (c == '-') f = true;
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		x = (x << 1) + (x << 3) + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    
    
    ll gcd(ll a, ll b) {
    	return b == 0 ? a : gcd(b, a%b);
    }
    int sqr(int x) { return x * x; }
    
    
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if (!b) {
    		x = 1; y = 0; return a;
    	}
    	ans = exgcd(b, a%b, x, y);
    	ll t = x; x = y; y = t - a / b * y;
    	return ans;
    }
    */
    
    struct node {
    	int u, v, w, nxt;
    }e[maxn];
    int head[maxn];
    int tot;
    int n;
    int dis[maxn], dep[maxn];
    int fa[maxn][20];
    void init() {
    	ms(e); ms(head); tot = 0; ms(dis); ms(dep);
    	ms(fa);
    }
    
    void addedge(int u, int v, int w) {
    	e[++tot].u = u; e[tot].v = v; e[tot].nxt = head[u]; e[tot].w = w;
    	head[u] = tot;
    }
    
    
    void dfs(int rt) {
    	for (int i = 1; i <= (int)log(n) / log(2) + 1; i++)
    		fa[rt][i] = fa[fa[rt][i - 1]][i - 1];
    	for (int i = head[rt]; i; i = e[i].nxt) {
    		int v = e[i].v;
    		if (v == fa[rt][0])continue;
    		fa[v][0] = rt; dep[v] = dep[rt] + 1;
    		dis[v] = dis[rt] + e[i].w;
    		dfs(v);
    	}
    }
    
    int LCA(int x, int y) {
    	if (dep[x] > dep[y])swap(x, y);
    	for (int i = (int)log(n) / log(2) + 1; i >= 0; i--) {
    		if (dep[fa[y][i]] >= dep[x])y = fa[y][i];
    	}
    	if (x == y)return x;
    	for (int i = (int)log(n) / log(2) + 1; i >= 0; i--) {
    		if (fa[x][i] != fa[y][i]) {
    			x = fa[x][i]; y = fa[y][i];
    		}
    	}
    	return fa[x][0];
    }
    
    int main()
    {
    //	ios::sync_with_stdio(0);
    	int T = rd();
    	while (T--) {
    		n = rd();
    		init();
    		for (int i = 1; i < n; i++) {
    			int u = rd(), v = rd(), w = rd();
    			addedge(u, v, w); addedge(v, u, w);
    		}
    		dfs(1);
    		char op[20];
    		while (rdstr(op) != EOF && op[1] != 'O') {
    			if (op[1] == 'I') {
    				int u = rd(), v = rd();
    			//	cout << dis[u] << ' ' << dis[v] << ' ' << dis[LCA(u, v)] << endl;
    				printf("%d
    ", dis[u] + dis[v] - 2 * dis[LCA(u, v)]);
    			}
    			else {
    				int u = rd(), v = rd(), k = rd();
    				int root = LCA(u, v);
    				int ans;
    				if (dep[u] - dep[root] + 1 >= k) {
    					ans = dep[u] - k + 1;
    					int i;
    					for (i = 0; (1 << i) <= dep[u]; i++); i--;
    					for (int j = i; j >= 0; j--) {
    						if (dep[u] - (1 << j) >= ans)u = fa[u][j];
    					}
    					printf("%d
    ", u);
    				}
    				else {
    					ans = dep[root] + k - (dep[u] - dep[root] + 1);
    					int i;
    					for (i = 0; (1 << i) <= dep[v]; i++); i--;
    					for (int j = i; j >= 0; j--) {
    						if (dep[v] - (1 << j) >= ans)v = fa[v][j];
    					}
    					printf("%d
    ", v);
    				}
    			}
    		}
    	}
    	return 0;
    }
    
    EPFL - Fighting
  • 相关阅读:
    树---对称的二叉树
    树---二叉树的下一个节点
    阿里一面电话面
    树---重建二叉树
    CVTE电话面
    聊聊平台型游戏
    Ogre-next with Visual Studio 2019, SDL Memset, CL.exe error
    中国能不能制作AAA游戏?
    Simple Cel Shading 钟馗
    Modeling -> Mixamo auto rigging -> UE4 retargeting
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10355532.html
Copyright © 2020-2023  润新知