zoukankan      html  css  js  c++  java
  • HDU 2586

    题意:

    一道很裸的LCA题

    以一个点建树,两点间最短的距离可以转化为求两近公共祖先,最短距离,depth[x]-depth[l]+depth[y]-depth[l]

    在dfs求得每个点到顶点距离

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn=4e4+5;
    const int maxbit=15;
    struct edge
    {
        int to;
        int val;
    };
    int father[maxn][maxbit];
    int depth[maxn];
    int dis[maxn];vector<edge>G[maxn];
    int lg[maxn];
    void dfs(int nowp,int fa)
    {
        depth[nowp]=depth[fa]+1;
        father[nowp][0]=fa;
        for(int j=1;j<=lg[depth[nowp]];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(depth[u]<depth[v])
        swap(u,v);
        while(depth[u]!=depth[v])
        u=father[u][lg[depth[u]-depth[v]]];
        if(u==v)return u;
        for(int j=lg[depth[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(depth,0,sizeof depth);
            memset(dis,0,sizeof dis);
            int n,m;
            scanf("%d%d",&n,&m);
            int x,y,k;
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&x,&y,&k);
                G[x].push_back({y,k});
                G[y].push_back({x,k});
            }
            dfs(1,0);
            while(m--)
            {
                scanf("%d%d",&x,&y);
                int l=lca(x,y);
                printf("%d
    ",(dis[x]-dis[l])+(dis[y]-dis[l]));
            }
        }
        return 0;
    }
  • 相关阅读:
    页脚保持在未满屏页面的底部
    jquery tab选项卡
    Unity 物体在屏幕内跟随鼠标移动
    Unity 中一些图形学知识
    Unity 简单的第三人称视角
    Unity 一个简单的鼠标跟随
    Unity常用操作代码
    3D渲染管线
    教你如何利用threejs对3D模型皮肤进行DIY
    从Maya中把模型搬运至网页的过程
  • 原文地址:https://www.cnblogs.com/flyljz/p/11687493.html
Copyright © 2011-2022 走看看