树上最短路

题目:

  给出一棵树进行如下操作:

          (1)把某个点上染黑

          (2)询问某个点,到最近黑点的距离。

          开始时,把‘1’点染黑。

  • 10% N,M ≤ 10
  • 40% N,M ≤ 100
  • 100% N ≤ 2 × 10 5 ,M ≤ 10 5

思路:(搜索的思路)

  每加入一个点就更新,最短路。记录答案。

一个剪枝:

  当你要更新的值大于或等于它原来的值时,就不用向后更新了。(因为后面的点肯定离另一个点比这个点近)

具体代码:

  bfs

  

复制代码
#include<iostream>
#include<cstdio>
#include<math.h>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,q[99999999];
int h[200009],next[400009],to[400009],cnt,ans[200009];
void bfs(int x)
{
    int l=0,r=1;
    int now,t;
    q[x]=x;ans[x]=1;
    while(l<=r)
    {
        now=q[++l];
        for(int i=h[x];i;i=next[i])
        {    t=to[i];        
            if(ans[now]+1<ans[t])
            {                
                ans[t]=ans[now]+1;
                q[++r]=t;
            }
        }
    }
}
int main()
{    
    freopen("travel.in","r",stdin);
    freopen("travel.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        to[++cnt]=y,next[cnt]=h[x],h[x]=cnt;
        to[++cnt]=x,next[cnt]=h[y],h[y]=cnt;        
    }
    memset(ans,0x7f,sizeof(ans));
    bfs(1);
    for(int i=1,A,B;i<=m;i++)
    {
        scanf("%d",&A);
        if(A==2)
        {
            scanf("%d",&B);
            printf("%d\n",ans[B]);
        }
        if(A==1)
        {
            scanf("%d",&B);
            bfs(B);
        }
    }
    return 0;
} 
复制代码

  dfs

复制代码
#include<iostream>
#include<cstdio>
#include<math.h>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int h[200009],next[400009],to[400009],cnt,ans[200009],last;
void dfs(int x,int last,int y)
{
    ans[x]=y;
    int t;
    for(int i=h[x];i;i=next[i])
    {    t=to[i];
        if(t!=last&&y+1<ans[t])
            dfs(t,x,y+1);    
    }
    return;
}
int main()
{    
    freopen("cicada.in","r",stdin);
    freopen("cicada.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        to[++cnt]=y,next[cnt]=h[x],h[x]=cnt;
        to[++cnt]=x,next[cnt]=h[y],h[y]=cnt;        
    }    
    memset(ans,0x7f,sizeof(ans)); 
    dfs(1,1,0);
    for(int i=1,A,B;i<=m;i++)
    {
        scanf("%d",&A);
        if(A==2)
        {
            scanf("%d",&B);
            printf("%d\n",ans[B]);
        }
        if(A==1)
        {
            scanf("%d",&B);
            dfs(B,B,0);
        }
    }
    return 0;
} 
复制代码

 

posted @   浪矢-CL  阅读(466)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示