zoukankan      html  css  js  c++  java
  • LCA问题的离线处理Tarjan算法模版

    Tarjan算法:

    http://blog.csdn.net/smallacmer/article/details/7432625

      1 //这个tarjan算法使用了并查集+dfs的操作。中间的那个并查集操作的作用,只是将已经查找过的节点捆成一个集合然后再指向一个公共的祖先。另外,如果要查询LCA(a,b),必须把(a,b)和(b,a)都加入邻接表。
      2 //
      3 //O(n+Q)
      4 
      5 #include <iostream>
      6 #include <cstdio>
      7 #include <cstring>
      8 #include <vector>
      9 
     10 using namespace std;
     11 
     12 #define MAXN 10001
     13 
     14 int n,fa[MAXN];
     15 int rank[MAXN];
     16 int indegree[MAXN];
     17 int vis[MAXN];
     18 vector<int> hash[MAXN],Qes[MAXN];
     19 int ances[MAXN];//祖先
     20 
     21 
     22 void init(int n)
     23 {
     24     for(int i=0;i<=n;i++)
     25     {
     26         fa[i]=i;
     27         rank[i]=0;
     28         indegree[i]=0;
     29         vis[i]=0;
     30         ances[i]=0;
     31         hash[i].clear();
     32         Qes[i].clear();
     33     }
     34 }
     35 
     36 int find(int x)
     37 {
     38     if(x != fa[x])
     39         fa[x]=find(fa[x]);
     40     return fa[x];
     41 }
     42 
     43 void unio(int x,int y)
     44 {
     45     int fx=find(x),fy=find(y);
     46     if(fx==fy) return ;
     47     if(rank[fy]<rank[fx])
     48         fa[fy]=fx;
     49     else
     50     {
     51         fa[fx]=fy;
     52         if(rank[fx]==rank[fy])
     53             rank[fy]++;
     54     }
     55 }
     56 
     57 void Tarjan(int u)
     58 {
     59     ances[u]=u;
     60     int i,size = hash[u].size();
     61     for(i=0;i<size;i++)
     62     {
     63         Tarjan(hash[u][i]);//递归处理儿子
     64         unio(u,hash[u][i]);//将儿子父亲合并,合并时会将儿子的父亲改为u
     65         ances[find(u)]=u;//此时find(u)仍为u,即
     66     }
     67     vis[u]=1;
     68     
     69     //查询
     70     size = Qes[u].size();
     71     for(i=0;i<size;i++)
     72     {
     73         if(vis[Qes[u][i]]==1)//即查询的另一个结点开始已经访问过,当前的u在此回合访问。
     74         {
     75             printf("%d\n",ances[find(Qes[u][i])]);//由于递归,此时还是在u
     76             return;
     77         }
     78     }
     79 }
     80 
     81 int main()
     82 {
     83     int t;
     84     int i,j;
     85     scanf("%d",&t);
     86     while(t--)
     87     {
     88         scanf("%d",&n);
     89         init(n);
     90         int s,d;
     91         for(i=1;i<=n-1;i++)
     92         {
     93             scanf("%d%d",&s,&d);
     94             hash[s].push_back(d);
     95             indegree[d]++;
     96         }
     97         scanf("%d%d",&s,&d);
     98     //    if(s==d)//如果需要计数的时候注意
     99 //            ans[d]++;
    100 //        else
    101 //        {
    102             Qes[s].push_back(d);
    103             Qes[d].push_back(s);
    104 //        }
    105         for(j=1;j<=n;j++)
    106         {
    107             if(indegree[j]==0)
    108             {
    109                 Tarjan(j);
    110                 break;
    111             }
    112         }
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    8.24Java入门--->第二十六节
    IDEA-->右键没有创建包选项--->新建包不能自动扩展
    8.21Java入门--->第二十五节(多线程)
    个人冲刺(一)——体温上报app(二阶段)
    个人作业——家庭记账本
    个人冲刺(五)——家庭记账本
    个人冲刺(四)——家庭记账本
    个人冲刺(三)——家庭记账本
    个人冲刺(二)——家庭记账本
    个人冲刺(一)——家庭记账本
  • 原文地址:https://www.cnblogs.com/Missa/p/2709749.html
Copyright © 2011-2022 走看看