hdu2586

7 篇文章 0 订阅
# include <iostream>
# include <cstdio>
# include <cstring>
# include <string>
# include <cmath>
# include <vector>
# include <map>
# include <queue>
# include <cstdlib>
# define MAXN 40001
using namespace std;

int n, mm, s;
int fa[MAXN], qx[MAXN], qy[MAXN], ans[MAXN], f[MAXN];
vector <int> vec[MAXN], q[MAXN];
struct node
{
    int x,y;
    node(int a,int b)
    {
        x=a,y=b;
    }
    bool operator <(const node &no)const
    {
        if(y!=no.y) return y<no.y;
        if(y==no.y)
            return (x<no.x );
    }
};
map<node,int> m;
inline int find(int x)
{
    return x == fa[x] ? x : find(fa[x]);
}

inline void dfs(int u)
{

    int i, v;
    fa[u] = u;
    for(i = 0; i < vec[u].size(); i++)
    {
        v = vec[u][i];
        if(f[u] != v) f[v] = u, dfs(v);

    }
    for(i = 0; i < q[u].size(); i++)
        if(f[v = u ^ qx[q[u][i]] ^ qy[q[u][i]]])//^运算获得与u相连的点(qx,qy中必有一个是u)
        {
            ans[q[u][i]] = find(v);
        }

    fa[u] = f[u];//这里f相当于vis数组
}
void solve()
{
    for(int i=1;i<=mm;i++)
    {
        int u=qx[i];
        int v=qy[i];
        int tmp=ans[i];
        int sum=0;
        while(v!=tmp)
        {
            sum+=m[node(v,fa[v])];
            v=fa[v];
        }
        while(u!=tmp)
        {
            sum+=m[node(u,fa[u])];
            u=fa[u];
        }
        ans[i]=sum;
    }
}
int main()
{
    int i, x, y,z;
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>mm;
        for(i = 1; i < n; i++)
        {
            cin>>x>>y>>z;
            m[node(x,y)]=z;
            m[node(y,x)]=z;
            vec[x].push_back(y);
            vec[y].push_back(x);
        }
        for(i = 1; i <= mm; i++)
        {
            cin>>qx[i]>>qy[i];
            q[qx[i]].push_back(i);
            q[qy[i]].push_back(i);
        }
        dfs(1);
        solve();
        for(i = 1; i <= mm; i++) printf("%d\n", ans[i]);
    }

    return 0;
}
/*
2
3 2
1 2 10
3 1 15
2 3
1 2

*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值