zoukankan      html  css  js  c++  java
  • Hdu 2586

    LCA离线算法的应用:在带权树中求任意两点的距离。
    "离线"是指求出答案之后保存起来,最后一起输出。(在一次遍历中把所有询问一次性解决。)
    Tarjan算法的基本步骤:
    1.任选一个点作为根节点,从该点开始dfs遍历
    2.遍历该点u的子树中所有节点,并标记这些点的被访问状态
    3.如果v还有子树中的节点未被访问,goto 2
    4.将v合并进u(使用并查集)
    5.寻找与当前节点有询问关系的点v
    6.如果v已经被访问,则可以确认u和v的最近公共祖先为v被合并后的父亲节点a;

    /**/
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cctype>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <vector>
    #include <string>
    #include <stack>
    #include <queue>
    
    typedef long long LL;
    typedef unsigned long long ULL;
    using namespace std;
    
    bool Sqrt(LL n) { return (LL)sqrt(n) * sqrt(n) == n; }
    const double PI = acos(-1.0), ESP = 1e-10;
    const LL INF = 99999999999999;
    const int inf = 999999999, N = 4e4 + 5;
    typedef pair<int, int> P;
    int T, n, m, d[N], fa[N], vis[N], ans[N];
    vector<P> G[N], Q[N];
    
    int fnd(int x) { return x == fa[x] ? x : fa[x] = fnd(fa[x]); }
    
    void dfs(int u, int v)
    {
    	fa[u] = u;
    	for(auto _cur : Q[u]) {
    		if(vis[_cur.first]) ans[_cur.second] = d[u] + d[_cur.first] - 2 * d[fnd(_cur.first)];
    	}
    	vis[u] = 1;
    	for(auto cur : G[u]) {
    		if(cur.first != v) {
    			d[cur.first] = d[u] + cur.second;
    			dfs(cur.first,u);
    			fa[cur.first] = u;
    		}
    	}
    }
    
    int main()
    {
    	//freopen("in.txt", "r", stdin);
    	//freopen("out.txt", "w", stdout);
    	scanf("%d", &T);
    	while(T--) {
    		scanf("%d%d", &n, &m);
    		memset(d, 0, sizeof d); memset(vis, 0, sizeof vis); memset(ans, 0, sizeof ans);
    		for(int i = 0; i <= n; i++) { G[i].clear(); Q[i].clear(); }
    		for(int i = 1; i < n; i++) {
    			int u, v, cost; scanf("%d%d%d", &u, &v, &cost);
    			G[u].push_back(P(v,cost)); G[v].push_back(P(u,cost));
    		}
    		for(int i = 1; i <= m; i++) {
    			int u, v; scanf("%d%d", &u, &v);
    			Q[u].push_back(P(v, i)); Q[v].push_back(P(u, i));
    		}
    		dfs(1, -1);
    		for(int i = 1; i <= m; i++) printf("%d
    ", ans[i]);
    	}
    
    	return 0;
    }
    /*
        input:
        output:
        modeling:
        methods:
        complexity:
        summary:
    */
    
  • 相关阅读:
    【反演复习计划】【bzoj2154】Crash的数字表格
    【反演复习计划】【bzoj3529】数表
    【反演复习计划】【bzoj3994】DZY loves maths
    【反演复习计划】【bzoj3994】约数个数和
    【反演复习计划】【bzoj2818】gcd
    【反演复习计划】【bzoj1011】zap-queries
    BZOJ3991: [SDOI2015]寻宝游戏
    BestCoder Round #75
    BZOJ4417: [Shoi2013]超级跳马
    BZOJ4416: [Shoi2013]阶乘字符串
  • 原文地址:https://www.cnblogs.com/000what/p/11698548.html
Copyright © 2011-2022 走看看