• HDU 5286 How far away ? lca


    题目链接:

    题目

    How far away ?
    Time Limit: 2000/1000 MS (Java/Others)
    Memory Limit: 32768/32768 K (Java/Others)

    问题描述

    There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.

    输入

    First line is a single integer T(T<=10), indicating the number of test cases.
    For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
    Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.

    输出

    For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.

    样例

    input
    2
    3 2
    1 2 10
    3 1 15
    1 2
    2 3

    2 2
    1 2 100
    1 2
    2 1

    output
    10
    25
    100
    100

    题意

    给你一颗树,问两点间距离

    题解

    离线求每个点的深度,则距离为dep[u]+dep[v]-2*dep[lca(u,v)];

    代码

    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define mp make_pair
    #define X first
    #define Y second
    using namespace std;
    
    const int maxn = 4e4+10;
    const int maxm = 18;
    
    int n, m;
    
    vector<pair<int, int> > G[maxn];
    int dep[maxn],dep2[maxn],anc[maxn][maxm];
    void dfs(int u,int fa,int d,int d2) {
    	dep[u] = d, dep2[u] = d2;
    	anc[u][0] = fa;
    	for (int j = 1; j < maxm; j++) {
    		int f = anc[u][j - 1];
    		anc[u][j] = anc[f][j - 1];
    	}
    	for (int i = 0; i < G[u].size(); i++) {
    		int v = G[u][i].X, w = G[u][i].Y;
    		if (v == fa) continue;
    		dfs(v, u, d + 1, d2 + w);
    	}
    }
    
    int Lca(int u, int v) {
    	if (dep[u] < dep[v]) swap(u, v);
    	for (int i = maxm - 1; i >= 0; i--) {
    		if (dep[anc[u][i]] >= dep[v]) {
    			u = anc[u][i];
    		}
    	}
    	if (u == v) return u;
    	for (int i = maxm - 1; i >= 0; i--) {
    		if (anc[u][i] != anc[v][i]) {
    			u = anc[u][i], v = anc[v][i];
    		}
    	}
    	return anc[u][0];
    }
    
    void init() {
    	for (int i = 0; i <= n; i++) G[i].clear();
    	memset(anc, 0, sizeof(anc));
    }
    
    int main() {
    	int tc;
    	scanf("%d", &tc);
    	while (tc--) {
    		scanf("%d%d", &n, &m);
    		init();
    		for (int i = 0; i < n - 1; i++) {
    			int u, v, w;
    			scanf("%d%d%d", &u, &v, &w);
    			G[u].push_back(mp(v, w));
    			G[v].push_back(mp(u, w));
    		}
    		dfs(1, 0,0,0);
    		while (m--) {
    			int u, v;
    			scanf("%d%d", &u, &v);
    			int lca = Lca(u, v);
    			printf("%d
    ", dep2[u] + dep2[v] - 2 * dep2[lca]);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    win10安装nodejs,修改全局依赖位置和环境变量配置
    JavaScript判断两个对象内容是否相等
    JS判断是否是数组
    Js判断值是否是NaN
    typeof方法重写(区分数组对象)
    JS实现图片懒加载
    输入url到展示页面过程发生了什么?
    html如何在服务端跑起来
    nuxt怎么打包
    如果scss引用了字体图标文件该怎么打包
  • 原文地址:https://www.cnblogs.com/fenice/p/5625455.html
Copyright © 2020-2023  润新知