• LCA的 Trajan 算法


    参考博客

    参考博客

    根据博客的模拟,就可以知道做法和思想。

    现在就是实现他。

    例题 :hdu  2586 

    题意:m 个询问,x  到  y  的距离,我们的思想就是求出:x到根的距离+y到根的距离-2*(lca[ x ,y ])到跟的距离。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int max_edge=100005;//边数
    const int max_Q=405;//问题
    const int max_=40005;//节点
    struct  Tree{//树-邻接表
       int to;
       int v;
       int next;
    };
    struct  Question{//离线-问题
       int to;
       int id;
       int next;
    };
    struct Tree a[max_edge];//树数组
    struct Question b[max_];//问题数组
    int N,M;
    int edge[max_];//边记录next
    int tot1,tot2;
    bool vis[max_];//标记数组
    int st[max_Q],ed[max_Q];//问题的x和y
    int question[max_];//问题-记录next
    int fa[max_];//父节点
    int dis[max_];//到根的距离
    int LCA[max_Q];//问题的LCA
    void  add_edge(int x,int y,int v)//建树
    {
        a[++tot1].to=y;
        a[tot1].v=v;
        a[tot1].next=edge[x];
        edge[x]=tot1;
    }
    void add_question(int x,int y,int id)//离线
    {
        b[++tot2].to=y;
        b[tot2].id=id;
        b[tot2].next=question[x];
        question[x]=tot2;
    }
    int find_fa(int x)//寻找父节点
    {
        if(fa[x]==x)
            return x;
        return fa[x]=find_fa(fa[x]);
    }
    void Tarjan(int x)
    {
        fa[x]=x;//作为当前的根节点,将其父亲指向自己
        vis[x]=1;//标记
        for(int i=question[x];i;i=b[i].next)//寻找问题中与自己有关节点
        {
            int go_to=b[i].to;
            if(vis[go_to]==true)//如果有关节点走过,记录LCA
                LCA[b[i].id]=find_fa(go_to);
        }
        for(int i=edge[x];i;i=a[i].next)//沿边遍历
        {
            int go_to=a[i].to;
            if(vis[go_to]==false)
                {
                    dis[go_to]=dis[x]+a[i].v;//更新距离
                    Tarjan(go_to);//递归遍历
                    fa[go_to]=x;//归并父节点
                }
        }
    }
    int main()
    {
        int T;
        cin>>T;//测试组数
        while(T--)
        {
            memset(vis,0,sizeof(vis));
            memset(question,0,sizeof(question));
            memset(edge,0,sizeof(edge));
            memset(dis,0,sizeof(dis));
            memset(LCA,0,sizeof(LCA));
            tot1=0,tot2=0;//初始归零
          cin>>N>>M;
          for(int i=0;i<N-1;i++)
          {
              int x,y,v;
              cin>>x>>y>>v;
              add_edge(x,y,v);//双向建边
              add_edge(y,x,v);
          }
          for(int i=0;i<M;i++)
          {
              int x,y;
              cin>>x>>y;
              add_question(x,y,i);
              add_question(y,x,i);//保证找有关点时不漏
              st[i]=x,ed[i]=y;//记录问题的x,y
          }
          Tarjan(1);
          for(int i=0;i<M;i++)
          {
              int temp=dis[st[i]]+dis[ed[i]]-(2*dis[LCA[i]]);//结果
              cout<<temp<<endl;
          }
        }
    }
  • 相关阅读:
    winform只允许一个应用程序运行
    IIS配置文件的XML格式不正确 applicationHost.config崩溃 恢复解决办法
    C#ToString() 格式化数值
    SQLServer2008只能编辑前面200行数据
    Validform验证时可以为空,否则按照指定格式验证
    js操作cookie
    div z-index无论设置多高都不起作用
    Tableau 练习题
    Tableau可视化操作
    Tableau 基础
  • 原文地址:https://www.cnblogs.com/linhaitai/p/9736115.html
Copyright © 2020-2023  润新知