How far away ? HDU - 2586 (LCA)

本文介绍了一道关于LCA(最近公共祖先)算法的问题,并通过一个具体的例子详细解释了如何运用LCA算法解决从一个房子到另一个房子之间的最短路径问题。文章提供了完整的代码实现,并附带了解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this “How far is it if I want to go from house A to house B”? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path(“simple” means you can’t visit a place twice) between every two houses. Yout task is to answer all these curious people.
Input

First line is a single integer T(T<=10), indicating the number of test cases.
For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k (1到40000).The houses are labeled from 1 to n.

Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
Output

For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3

2 2
1 2 100
1 2
2 1
Sample Output
10
25
100
100

一道LCA的题,第一次接触,网上查了查,根据原理(我参考的是这篇文章,只有方法,没有代码的http://www.cnblogs.com/ECJTUACM-873284962/p/6613379.html),按照自己的理解,写了代码,到现在了,应该要有提供思路,便有写代码的能力(也就是说现在的阶段应该提升思维,拓展思路最为重要),所以我所写的应该还有待优化的地方。这个代码是其中一种实现LCA的方式,有离线的思想
代码

#include<cstdio>
#include<iostream>
#include<map>
#include<cstring>
#include<vector>
#define maxn 6006
using namespace std;
struct node
{
    int a,b;
}query[203];//离线保留询问
int ans[203];//询问对应的答案
struct edge
{
    int to;
    int dis;
};//保留边
bool vis[203];
int n,m;
int pre[40004];
bool vis2[40004];
int dis[40004];
vector<edge>tree[40004];
void getDis(int x,int father)//求出所有点到根节点的距离
{
    int v;
    for(int i=0;i<tree[x].size();i++)
    {
        v=tree[x][i].to;
        if(v==father)
            continue;
        dis[v]=dis[x]+tree[x][i].dis;
        getDis(v,x);
    }
}
int findd(int x)//使用并查集,但是个人理解和并查集没有太大关系,只是借用了并差集的实现方式
{
    return pre[x]==x?x:pre[x]=findd(pre[x]);
}
void LCA(int x,int father)//LCA啦
{
    int v;
    for(int i=0;i<tree[x].size();i++)
    {
        v=tree[x][i].to;
        if(v==father)
            continue;
        LCA(v,x);
    }
    for(int i=0;i<m;i++)//对于200的询问量,线性扫一遍即可
    {
        if(vis[i])
            continue;
        if(x==query[i].a&&vis2[query[i].b])
        {
            ans[i]=dis[x]+dis[query[i].b]-2*dis[findd(query[i].b)];
            vis[i]=true;
        }
        else
        {
            if(x==query[i].b&&vis2[query[i].a])
            {
                ans[i]=dis[x]+dis[query[i].a]-2*dis[findd(query[i].a)];
                vis[i]=true;
            }
        }
    }
    int xx=findd(x);
    pre[xx]=father;
    vis2[x]=true;
}
int main()
{
    dis[1]=0;//根到自己的距离当然为0
    int t;
    int a,b,w;
    scanf("%d",&t);
    while(t--)
    {

        memset(vis,false,sizeof(vis));
        memset(vis2,false,sizeof(vis2));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            tree[i].clear();
        for(int i=1;i<=n;i++)
            pre[i]=i;//都是初始化,其实我很少写init()函数,因为不知道为什么总是忘了写到main里。。。
        for(int i=1;i<n;i++)
        {
           scanf("%d%d%d",&a,&b,&w);
           edge e;
           e.dis=w;
           e.to=a;
           tree[b].push_back(e);//存边
           e.to=b;
           tree[a].push_back(e);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            query[i].a=a;
            query[i].b=b;//村存查询
        }
        getDis(1,-1);
        //cout<<"yes";
        LCA(1,-1);
        for(int i=0;i<m;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

入门LCA的一道好题,难度不大

内容概要:本文档是Kenwood TK-6110 VHF FM收发器的操作手册,详细介绍了设备的基本功能、安装步骤和操作指南。手册首先感谢用户选择Kenwood产品,并强调了设备的安全性和合规性,包括FCC警告和政府法律禁止未经授权的无线电台操作。接着,手册逐步指导用户进行设备的拆箱检查、安装准备(如工具、电源连接)、安装步骤以及熟悉设备的前面板、后面板和麦克风布局。此外,还涵盖了基本操作(如开关机、音量调整、频道选择和通话)以及辅助功能(如定时断电、忙道锁定、双音多频呼叫等)。最后,提供了关于DTMF呼叫(手动拨号、重拨、自动拨号)的具体操作步骤。 适合人群:适用于需要使用Kenwood TK-6110 VHF FM收发器的专业用户或技术人员,特别是那些负责安装和维护移动通信设备的人员。 使用场景及目标:①帮助用户正确安装和配置Kenwood TK-6110 VHF FM收发器,确保其在车辆或其他移动平台上安全可靠地运行;②指导用户掌握设备的基本操作技能,如频道选择、通话、信号发送等;③提供详细的辅助功能设置说明,使用户能够充分利用设备的各种高级功能,如定时断电、忙道锁定、双音多频呼叫等。 其他说明:用户应仔细阅读并遵守所有安全警告和操作指南,以避免潜在的危害和法律问题。建议在安装和使用过程中咨询授权经销商或专业技术人员,以确保设备的正常运行和最佳性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值