HDU2586(LCA问题)

(important) 树中root到每一个node都存在唯一路径,

// dfs(root)   dis[node]求出root到node节点的距离

//so len(u,v)   =   dis[u] + dis[v] - 2dis[LCA(u,v)];            //LCA比较简单不谈,但初始化要放在函数外,很奇怪,坑了我1h

//实锤水题垃圾

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
const int maxn = 4e4 + 15;
int n,m,sum;//n node,m query
bool rudu[maxn];
typedef struct
{
    int v,value;
}edge;
vector<edge> Grape[maxn];
int query[maxn][2];// 0 ~ u / 1 ~ v
int arr[maxn];//每个查询的结果
bool vis[maxn];
int father[maxn];
int dis[maxn];
int find(int u)
{
    if(u!=father[u])
        father[u] = find(father[u]);
    return father[u]; 
}
void Tarjan(int u)
{
    for(int i=0;i!=Grape[u].size();++i)
    {
        int v = Grape[u][i].v;//相邻节点
        Tarjan(v);
        father[v] = u;
    }
    vis[u] = true;
    for(int i=0;i!=m;++i)
    {
        int ans;
        if(u==query[i][0]&&vis[query[i][1]])
        {
            ans = find(query[i][1]);
            arr[i] = ans;
        }            
        if(u==query[i][1]&&vis[query[i][0]])
        {
            ans = find(query[i][0]);
            arr[i] = ans;
        }
    }
}
//bool flag[maxn];
void dfs(int root)
{
    //flag[root] = true;
    for(int i=0;i!=Grape[root].size();++i)
    {
        int v = Grape[root][i].v;
        sum += Grape[root][i].value;
        dis[v] = sum;
        dfs(v);
        sum -= Grape[root][i].value;
    }
}
int main()
{
    int T,u,v;  cin>>T;
    while(T--)
    {
        cin>>n>>m;
        for(int i=1;i<=n;++i)
        {
            father[i] = i;
            Grape[i].clear();//清空图
        }
        memset(rudu,false,sizeof(rudu));
        memset(query,0,sizeof(query));
        memset(arr,0,sizeof(arr));
        memset(vis,false,sizeof(vis));
        edge node;
        for(int i=0;i!=n-1;++i)
        {
            cin>>u>>node.v>>node.value;
            rudu[node.v] = true;
            Grape[u].push_back(node);
        }//带权值的边
        for(int i=0;i!=m;++i)
        {
            cin>>query[i][0]>>query[i][1];
        }
        int root;
        for(int v=1;v<=n;++v)
            if(!rudu[v])
            {
                root = v;//根节点
                Tarjan(v);
            }
        //arr存储父节点
        //dfs 根到图中各节点的距离
        //for(int i=0;i!=m;++i)
        //    cout<<arr[i]<<endl;
        sum = 0;//根到各个节点的距离
        memset(dis,0,sizeof(dis));
       // memset(flag,false,sizeof(flag));
        dfs(root);
        //for(int i=1;i<=n;++i)
        //    cout<<dis[v]<<endl;
        for(int i=0;i!=m;++i)
        {
            cout<<dis[query[i][0]]+dis[query[i][1]] - 2*dis[arr[i]]<<endl;
        }
    }
}

  

不怕万人阻挡,只怕自己投降。
原文地址:https://www.cnblogs.com/newstartCY/p/11591823.html