LCA hdu2586

hdu 2586
dp[x][i]表示節點i往上走2^i次所到達的祖先,那麼不難寫出轉移方程:
dp[x][i]=dp[dp[x][i-1]][i-1];
然後在求LCA的時候,有這樣一個性質:(假設a和b深度一樣)
於是求法就漸漸的現行了:
1. 把a和b移到同一深度(設deep[x]爲節點x的深度),假設deep[a]<=deep[b],所以我們的目的是把b向上 移動i=(deep[b]-deep[a])層,那麼,由於之前有預處理的dp數組,我們把i寫成二進制形勢,然後利用dp數 組來在log n的複雜度中完成;
2. 尋找a和b的LCA下一層的兩個祖先。利用之前的那個性質,再利用倍增,如果a和b的第2^k個祖先不是
同一個,那麼a=dp[a][k],b=dp[b][k];當然在這之前要實現確定k的最大值,從大往小處理下去。最終的
結果就是dp[a][0];
注意點:如果a和b在調節深度之後已經是同一個祖先的,那麼直接返回a或者b。

//#include <bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf  0x7fffffff
#define linf 0x7fffffffffffffff
#define fil(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define debug printf("!!\n");
#define N 1000005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);// freopen("in.txt","r",stdin);
using namespace std;
typedef long long  ll;
typedef double db;
int n,s;
struct node
{
    int go,t;
};
int fa[100005],deep[100005],dp[100005][17],dis[100005];
vector<node> q[100005];
void dfs(int x,int dep)
{
    deep[x]=dep;
    dp[x][0]=fa[x];
    for(int i=1;(1<<i)<deep[x];i++)
        dp[x][i]=dp[dp[x][i-1]][i-1];
    for(int i=0;i<q[x].size();i++)
    {
        node tp=q[x][i];
        if(tp.go!=fa[x])
        {
            dis[tp.go]=dis[x]+tp.t;
            fa[tp.go]=x;
            dfs(tp.go,dep+1);
        }
    }
}
int lca(int a,int b)
{
    if(deep[a]>deep[b]) swap(a,b);
    int k=deep[b]-deep[a];

    for(int i=0;i<=19;i++)
        if((1<<i)&k) b=dp[b][i];


    for(int i=19;i>=0;i--)
        if(dp[a][i]!=dp[b][i]) a=dp[a][i],b=dp[b][i];
    if(a==b) return a;
    return dp[a][0];
}
int main()
{
    int tt;
    sd(tt);
    while(tt--)
    {
        fil(dis,0);
        fil(dp,0);
        fil(deep,0);
        fil(fa,0);
        int n,m;
        sdd(n,m);
        fup(i,1,n-1)
        {
            int x,y,z;
            sddd(x,y,z);
            q[x].push_back(node{y,z});
            q[y].push_back(node{x,z});
        }
        dfs(1,1);
        while(m--)
        {
            int x,y;
            sdd(x,y);
            pf(dis[x]+dis[y]-2*dis[lca(x,y)]);
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章