hdu-2586-How far away ?(离线LCA)

题意:

给定一棵树,每条边都有一定的权值,q次询问,每次询问某两点间的距离。

分析:

这样就可以用LCA来解,首先找到u, v 两点的lca,然后计算一下距离值就可以了。

这里的计算方法是,记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - 2 * dis[lca(v, v)]。

// File Name: 2586.cpp
// Author: Zlbing
// Created Time: 2013年08月19日 星期一 10时59分47秒
#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
const int MAXN=4e4+100;
struct Edge
{
    int u,v,cost;
    Edge()
    {
    }
    Edge(int u,int v,int cost):u(u),v(v),cost(cost)
    {
    }
};
vector<Edge> edges;
vector<Edge> qedges;
vector<int> G[MAXN],Q[MAXN];
int vis[MAXN];
int dis[MAXN];
int in[MAXN];
int f[MAXN];
int find(int x)
{
    return f[x]==x?x:f[x]=find(f[x]);
}
void LCA(int u,int fa)
{
    for(int i=0;i<(int)G[u].size();i++)
    {
        Edge e=edges[G[u][i]];
        if(e.v==fa)continue;
        dis[e.v]=dis[u]+e.cost;
        LCA(e.v,u);
        f[find(e.v)]=u;
    }
    vis[u]=1;
    for(int i=0;i<(int)Q[u].size();i++)
    {
        Edge& e=qedges[Q[u][i]];
        if(vis[e.v])
        {
            int ancestor=find(e.v);
            qedges[Q[u][i]].cost=dis[e.v]+dis[e.u]-2*dis[ancestor];
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        REP(i,1,n)
        {
            G[i].clear();
            Q[i].clear();
            vis[i]=0;
            dis[i]=0;
            in[i]=0;
            f[i]=i;
        }
        edges.clear();
        qedges.clear();
        int a,b,c;
        REP(i,1,n-1)
        {
            scanf("%d%d%d",&a,&b,&c);
            in[b]++;
            edges.push_back(Edge(a,b,c));
            edges.push_back(Edge(b,a,c));
            int mm=edges.size();
            G[a].push_back(mm-2);
            G[b].push_back(mm-1);
        }
        REP(i,1,m)
        {
            scanf("%d%d",&a,&b);
            qedges.push_back(Edge(a,b,-1));
            qedges.push_back(Edge(b,a,-1));
            int mm=qedges.size();
            Q[a].push_back(mm-2);
            Q[b].push_back(mm-1);
        }
        for(int i=1;i<=n;i++)
        {
            if(!in[i])
                LCA(i,-1);
        }
        for(int i=0;i<(int)qedges.size();i++)
        {
            Edge e=qedges[i];
            if(e.cost!=-1)
            {
                printf("%d\n",e.cost);
            }
        }
    }
    return 0;
}

 

posted @ 2013-08-20 11:39  z.arbitrary  阅读(308)  评论(0编辑  收藏  举报