小A的最短路

小A的最短路

https://ac.nowcoder.com/acm/problem/23482

题意:
有一颗n个节点的树,经过一条边消耗一点体力。有两个特殊点之间有一个观光缆车,他们之间不需要消耗体力。有Q个询问,每个询问求从x点到y点消耗体力值最少为多少?

思路:
求任意两点树上的距离应该用LCA.
由于多了个电缆,所以我们从x到y是有3种方案:
①从x直接到y,不坐电缆。
②从x到u,再从u坐电缆到v,最后从v到y。
③从x到v,再从v坐电缆到u,最后从u到y。
我们取这三种方案的最少值就可以了

注意:
lca写的丑的会被卡时间,由于u,v固定,所以可以用dfs先求出树上每一个节点到u,v的距离进行优化。

代码:

#include <bits/stdc++.h>

typedef long long ll;

using namespace std;

const ll inf=998244353;

inline int read()
{
    int x=0, y=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
        {
            y=-y;
        }
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x*y;
}

vector<int> g[300005];
int dep[300005], parent[20][300005];
int n;

void dfs(int v,int f,int d)
{
    dep[v]=d;
    parent[0][v]=f;
    for(int k=0;(1<<(k+1))<=dep[v];k++)
    {
         if(parent[k][v]<0)
         {
             parent[k+1][v]=-1;
             break;
         }
         else
         {
             parent[k+1][v]=parent[k][parent[k][v]];
         }
    }
    for(int i=0;i<g[v].size();i++)
    {
        if(g[v][i]!=f)
        {
            dfs(g[v][i],v,d+1);
        }
    }
}

int d1[300005], d2[300005];

void dfs1(int v,int f,int d)
{
    d1[v]=d;
    for(int i=0;i<g[v].size();i++)
    {
        if(g[v][i]!=f)
        {
            dfs1(g[v][i],v,d+1);
        }
    }
}

void dfs2(int v,int f,int d)
{
    d2[v]=d;
    for(int i=0;i<g[v].size();i++)
    {
        if(g[v][i]!=f)
        {
            dfs2(g[v][i],v,d+1);
        }
    }
}

void inti()
{
    memset(parent,-1,sizeof(parent));
    dfs(1,-1,0);
}

int lca(int u,int v)
{
    if(dep[u]<dep[v])
    {
        swap(u,v);
    }
    int s=(int)log2(n);
    for(int k=s;k>=0;k--)
    {
        if((dep[u]-dep[v])>=(1<<k))
        {
            u=parent[k][u];
        }
    }
    if(u==v)
    {
        return u;
    }
    for(int k=s;k>=0;k--)
    {
        if(parent[k][v]!=parent[k][u])
        {
            u=parent[k][u];
            v=parent[k][v];
        }
    }
    return parent[0][u];
}

int dis(int x, int y)
{
    return dep[x]+dep[y]-2*dep[lca(x,y)];
}

int main()
{
    n=read();
    for(int i=1;i<n;i++)
    {
        int u=read(), v=read();
        g[u].push_back(v);
        g[v].push_back(u);
    }
    inti();
    int u, v;
    u=read();
    v=read();
    dfs1(u,-1,0);
    dfs2(v,-1,0);
    int q=read();
    while(q--)
    {
        int x=read(), y=read();
        printf("%d\n",min(dis(x,y),min(d1[x]+d2[y],d1[y]+d2[x])));
    }
    return 0;
}
全部评论

相关推荐

双飞二本嵌入式求拷打我是在&nbsp;BOSS&nbsp;上投递的简历,好多都没人回复,这是开场白和简历求大神帮忙看看。您好!我是2025届应届生,最快可在一周内上岗,能够实习六个月以上,并接受加班。以下是我的核心优势和相关经验:1.&nbsp;嵌入式开发能力:&nbsp;&nbsp;&nbsp;熟练掌握STM32系列单片机及其外设(如GPIO、定时器、ADC、DAC、I2C、SPI、UART等),能够独立完成硬件驱动开发和调试。&nbsp;&nbsp;熟悉FreeRTOS实时操作系统,具备多任务调度和资源管理经验。&nbsp;&nbsp;熟悉LVGL图形库开发,能够实现嵌入式设备的图形界面设计。2.&nbsp;硬件设计能力:&nbsp;&nbsp;&nbsp;具备PCB设计经验,曾为2023年工创赛物流搬运赛道设计小车主板,带领团队获得国家级银奖。&nbsp;&nbsp;&nbsp;熟悉硬件原理图分析,能够快速理解并调试硬件电路。3.&nbsp;机器人开发与竞赛经验:&nbsp;&nbsp;&nbsp;在全国大学生智能车竞赛、ROS机器人竞赛中多次获得国家级奖项,具备丰富的机器人开发经验。&nbsp;&nbsp;&nbsp;熟悉Linux环境,对ROS和ROS&nbsp;2有一定了解,能够进行机器人系统的开发与调试。4.&nbsp;编程能力:&nbsp;&nbsp;&nbsp;熟悉C/C++,熟悉Python,能够高效完成嵌入式开发和算法实现。&nbsp;&nbsp;&nbsp;具备良好的代码规范和文档编写能力。5.&nbsp;团队协作与领导能力:&nbsp;&nbsp;&nbsp;在多个项目中担任核心开发或团队负责人,具备良好的沟通能力和团队协作精神。&nbsp;&nbsp;&nbsp;在工创赛中带领团队完成项目规划、任务分配和技术攻关,展现了较强的领导力。我对嵌入式开发、机器人技术和智能硬件充满热情,期待加入贵公司,与团队共同成长,为公司创造价值!如果有合适的岗位,欢迎随时联系我,期待进一步沟通!
沉淀一会:嵌入式就是狗屎
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务