Problem C

///LCA对树进行遍历, 过程中记录遍历过的路径,  树的任意两点的简单距离都是唯一的, 算出记录的路径的长度就是答案,

 

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <stack>
#include <algorithm>
//#include "myAlgorithm.h"

#define MAX 40005
#define OFFENCE (1e9 + 5)
#define INF (1e8 + 5)
#define eps 1e-9
#define Rep(s, e) for( int i = s; i <= e; i++)
#define Cep(e, s) for( int i = e; i >= s; i --)
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
using namespace std;
int T;
int n, m;
struct Edge{
    int pos;
    int val;
    int next;
}ed[MAX * 2];
int head[MAX], e;
vector<vector<int> >qurey;
void insert(int a, int b, int val){
    ed[e].next = head[a];
    ed[e].pos = b;
    ed[e].val = val;
    head[a] = e++;
}

int fa[MAX], lca[MAX], ansq[MAX];
struct Predge
{
    int pos, val;
}pre[MAX];
bool v[MAX];
int find(int x){
    return x== fa[x]? x:fa[x] = find(fa[x]);
}

int get_dist(int near, int i)
{
    int t = i;
    int ans = 0;
    while(t!= near){
        ans += pre[t].val;
        t = pre[t].pos;
        //cout<<"looping "<<endl;
    }
    return ans;
}
void LCA(int node,int father)
{
    //cout<<node<<endl;
    fa[node] = node;
    lca[node] = node;
    int next  = head[node], pos;
    while(next != -1){
        pos = ed[next].pos;
        if((pos != father && !v[pos])){
            pre[pos].pos = node;
            pre[pos].val = ed[next].val;
            LCA(pos, node);
            fa[pos] = node;
            lca[node] = node;
        }
        next = ed[next].next;
    }
    v[node] = 1;
    int len = qurey[node].size();
    for(int i  =  0; i < len; i += 2){
        pos = qurey[node][i];
        if(v[pos]){
            int nest = lca[find(pos)], t;
            int ans = get_dist(nest, node) + get_dist(nest, pos);
            ansq[qurey[node][i + 1]] = ans;
            //cout<<ans<<endl;
        }
    }
}
int main(){
    cin>>T;
    while(T--){
        cin>>n>>m;
        e  = 0;
        memset(head, -1, sizeof(int ) * (n + 1));
        memset(v, 0, sizeof(v));
        int a, b, val;
        Rep(1, n-  1){
            cin>>a>>b>>val;
            insert(a, b, val);
            insert(b, a, val);
        }
        qurey.assign(n+ 1, vector<int>() );
        int s, e;
        Rep(1, m){
            cin>>s>>e;
            qurey[s].push_back(e);
            qurey[e].push_back(s);
            qurey[s].push_back(i);
            qurey[e].push_back(i);
        }
        pre[1].pos = 1;
        pre[1].val = 0;
        //cout<<"start comput"<<endl;
        LCA(1, -1);
        Rep(1, m){
            cout<<ansq[i]<<endl;
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值