• LCA---Tarjan算法


           本问题中Tarjan算法不需要设置栈和dfn,low标号,而是设置了并查集。

             通过一次dfs遍历即可找出所有节点对的lca。将这样一次读取所有查询,计算一次后返回所有查询lca的算法称为离线算法 

             涉及到在线算法和离线算法这两个概念的算法还有区域最值查询问题(RMQ问题)。

          以下方法均可用于有向图【先查找出根节点root,再DFS】和无向图【root可以任意设置或者是直接遍历所有节点】

          原图和询问可以存储为【链式向前型】和【邻接表】的形式,注意定义形式即可。

    【1】使用union函数

     1 void LCA_Tarjan(int u)
     2 {
     3     int now_to;
     4     int i;
     5 
     6     vis[u]=1;   //标记+访问+遍历
     7     ancestor[u]=u;
     8     for(i=Tnode[u].pre;i!=-1;i=Tedge[i].pre)
     9     {
    10         now_to=Tedge[i].to_vertex;
    11         if(!vis[now_to])
    12         {
    13             LCA_Tarjan(now_to);
    14             Union(u,now_to);
    15                 ancestor[Find(now_to)]=u;  //ancestor[Find(u)]=u;  效果一样
    16         }
    17     }
    18     for(i=Qnode[u].pre;i!=-1;i=Qedge[i].pre)
    19     {
    20         now_to=Qedge[i].to_vertex;
    21         if(vis[now_to])
    22         {
    23             lca[Qedge[i].num]=ancestor[Find(now_to)]; //单独开数组存储
    24                  //     Qedge[2*Qedge[i].num-1].ans=Qedge[2*Qedge[i].num].ans=ancestor[Find(now_to)];
    25         }
    26     }
    27 }

    【2】不使用union函数

     1 void LCA_Tarjan(int u)
     2 { 
     3     int now_to;   
     4     int i; 
     5     
     6     vis[u]=1;  //标记+访问+遍历
     7     f[u]=u;   //将其父亲(根)指向自己
     8     for(i=Tnode[u].pre;i!=-1;i=Tedge[i].pre) /
     9     {
    10         now_to=Tedge[i].to_vertex;
    11         if(!vis[now_to])
    12         {
    13             LCA_Tarjan(now_to);
    14             f[now_to]=u;  //存储当前最近公共祖先
    15         }
    16     }
    17 
    18     for(i=Qnode[u].pre;i!=-1;i=Qedge[i].pre)  
    19     {
    20         now_to=Qedge[i].to_vertex;
    21         if(vis[now_to])  //如果其子节点及子节点的子树全部访问完才会进入这一步,由vis判断
    22         {                //如果已经访问了问题节点,就可以返回结果
    23                     lca[Qedge[i].num]=Find(now_to);
    24                    //    Qedge[2*Qedge[i].num-1].ans=Qedge[2*Qedge[i].num].ans=Find(now_to);  /*均可*/
    25         }
    26     }
    27 }
    ---  纵使山重水复,亦会柳暗花明   sunqh1991@163.com   欢迎关注,互相交流
  • 相关阅读:
    local 不能解析为127.0.0.1
    完全使用接口方式调用WCF 服务
    【人生】自己对于求职应聘的一些感受
    OO的经典例子
    剪刀、石头、布机器人比赛
    TextTree 文本资料收集轻量级工具
    两个代替重复输入的小工具
    桌面助手 Desktop Helper 自动帮你关闭指定的窗口
    磁盘可用空间平衡
    用C#制造可以继承的“枚举”
  • 原文地址:https://www.cnblogs.com/wjcx-sqh/p/5929922.html
Copyright © 2020-2023  润新知