zoukankan      html  css  js  c++  java
  • Tarjan求lca

    https://vjudge.net/problem/POJ-1330

    是到水的题,简单点在于其只需求一对lca即可,这是比较简单的。

    主要看了以下blog

    http://blog.csdn.net/hnust_xiehonghao/article/details/9109295

    要点在于

    1.用并查集维护。

    2.必须是离线的,在线不行。

    3.存边可以用vector,比较方便,毕竟边不多。

    *4.rank可以实现启发式并查集,可以优化一些时间。

    5.anse数组是存祖先的,因为并查集维护,所以只需一步更新即可。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<string>
     6 #include<cstring>
     7 #include<vector>
     8 const int size=10007;
     9 
    10 int n,f[size],anse[size],in[size],rank[size],vis[size];
    11 using namespace std;
    12 vector<int> node[size],que[size];
    13 void init();
    14 int find(int num);
    15 void conbine(int aa,int bb);
    16 void lca(int root)
    17 {
    18     int i,sz;
    19     anse[root]=root;
    20     sz=node[root].size();
    21     for (int i=0;i<sz;i++)
    22     {
    23     //    if (fa!=node[root][i])
    24     //    {
    25             lca(node[root][i]);
    26             conbine(root,node[root][i]);
    27             anse[find(node[root][i])]=root;
    28     //    }
    29     }
    30     vis[root]=1;
    31     sz=que[root].size();
    32     for (int i=0;i<sz;i++)
    33     {
    34         if (vis[que[root][i]])
    35         {
    36             printf("%d
    ",anse[find(que[root][i])]);
    37             return;
    38         }
    39     }
    40 }
    41 int main()
    42 {
    43     int cas,i;
    44     scanf("%d",&cas);
    45     while (cas--)
    46     {
    47         int x,y;
    48         scanf("%d",&n);
    49         init();
    50         for (int i=1;i<=n-1;i++)
    51         {
    52             scanf("%d%d",&x,&y);
    53             node[x].push_back(y); 
    54             in[y]++;
    55         }
    56         scanf("%d%d",&x,&y);
    57         que[x].push_back(y);
    58         que[y].push_back(x);
    59         for (y=1;y<=n;y++)
    60         {
    61             if (in[y]==0) break;
    62         }
    63         lca(y);
    64     }
    65 }
    66 void init()
    67 {
    68     int i;
    69     for (int i=1;i<=n;i++)
    70     {
    71         node[i].clear();
    72         que[i].clear();
    73         f[i]=i;
    74         rank[i]=1;
    75     }
    76     memset(vis,0,sizeof(vis));
    77     memset(in,0,sizeof(in));
    78     memset(anse,0,sizeof(anse));
    79 }
    80 int find(int num)
    81 {
    82     if (f[num]!=num) f[num]=find(f[num]);
    83     return f[num];
    84 }
    85 void conbine(int aa,int bb)
    86 {
    87     int x=find(aa),y=find(bb);
    88     if (x==y) return;
    89     if (rank[x]<=rank[y])
    90     {
    91         f[x]=y;
    92         rank[y]+=rank[x];
    93     }
    94     else
    95     {
    96         f[y]=x;
    97         rank[x]+=rank[y];
    98     }
    99 }

    求在线算法要用倍增lca

  • 相关阅读:
    C#: Create a WebRequest with HTTP Basic Authentication
    C# 集合
    BAT CMD 批处理文件脚本 -2
    年龄排序
    士兵买香蕉
    ACM交换生问题
    ACM卡片游戏
    ACM费马大定理
    ACM定外卖问题
    ACM汽车行程问题求最少的支付钱数
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/6775445.html
Copyright © 2011-2022 走看看