LCA 倍增

旧时模样 提交于 2019-12-03 04:54:21

HDU 2586

#include<bits/stdc++.h>
using namespace std;
const int maxn=4e4+4;
const int maxbit=15;
struct edge{
    int to;
    int val;
//    edge(int a,int b)
//    {
//        to=a;
//        val=b;
//    }
};
int father[maxn][maxbit];
int dep[maxn];
int dis[maxn];
int lg[maxn];
vector<edge> g[maxn];
void dfs(int nowp,int fa)
{
    dep[nowp]=dep[fa]+1;
    father[nowp][0]=fa;
    for(int j=1;j<=lg[dep[nowp]]+1;++j)
    {
        father[nowp][j]=father[father[nowp][j-1]][j-1];
    }
    for(int i=0;i<g[nowp].size();++i)
    {
        edge &e=g[nowp][i];
        if(e.to!=fa)
        {
            dis[e.to]=dis[nowp]+e.val;
            dfs(e.to,nowp);
        }
    }
}
int lca(int u,int v)
{
    if(dep[u]<dep[v])
        swap(u,v);
    while(dep[u]!=dep[v])
    {
        u=father[u][lg[dep[u]-dep[v]]];
    } 
    if(u==v) return u;
    for(int j=lg[dep[u]];j>=0;--j)
    {
        if(father[u][j]!=father[v][j])
        {
            u=father[u][j];
            v=father[v][j];
        }
    }
    return father[u][0];
}
int main()
{
    lg[0]=-1;
    for(int i=1;i<maxn;++i)
    {
        lg[i]=lg[i>>1]+1;
    } 
    int t;
    scanf("%d",&t);
    while(t--)
    {    
        memset(father,0,sizeof(father));
        memset(dep,0,sizeof(dep));
        memset(dis,0,sizeof(dis));
        for(int i=0;i<maxn;++i)
        {
            g[i].clear();
        }
        int n,m;
        scanf("%d%d",&n,&m);
        int x,y,k;
        for(int i=1;i<=n-1;++i)
        {
            scanf("%d%d%d",&x,&y,&k);
            g[x].push_back({y,k});
            g[y].push_back({x,k});
//            g[x].push_back(edge(y,k));
//            g[y].push_back(edge(x,k));
        }
        dfs(1,0);
        while(m--)
        {
            scanf("%d%d",&x,&y);
            int LCA=lca(x,y);
            printf("%d\n",dis[x]+dis[y]-2*dis[LCA]);
        }
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!