zoukankan      html  css  js  c++  java
  • POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)

    LCA问题的tarjan解法模板

    LCA问题 详细

    1、二叉搜索树上找两个节点LCA

    
    
     1 public int query(Node t, Node u, Node v) {    
     2     int left = u.value;    
     3     int right = v.value;    
     4 
     5     //二叉查找树内,如果左结点大于右结点,不对,交换  
     6     if (left > right) {    
     7         int temp = left;    
     8         left = right;    
     9         right = temp;    
    10     }    
    11 
    12     while (true) {    
    13         //如果t小于u、v,往t的右子树中查找  
    14         if (t.value < left) {    
    15             t = t.right;    
    16 
    17         //如果t大于u、v,往t的左子树中查找  
    18         } else if (t.value > right) {    
    19             t = t.left;    
    20         } else {    
    21             return t.value;    
    22         }    
    23     }    
    24 }  
    View Code
    
    

    2、二叉树上找两个节点

     1 node* getLCA(node* root, node* node1, node* node2)  
     2 {  
     3     if(root == null)  
     4         return null;  
     5     if(root== node1 || root==node2)  
     6         return root;  
     7 
     8     node* left = getLCA(root->left, node1, node2);  
     9     node* right = getLCA(root->right, node1, node2);  
    10 
    11     if(left != null && right != null)   // 两个点在root的左右两边,就是root了
    12         return root;  
    13     else if(left != null)  // 哪边不空返回哪边  
    14         return left;  
    15     else if (right != null)  
    16         return right;  
    17     else   
    18         return null;  
    19 }  
    View Code
    朴素法求解: 先对树进行dfs标出每一个节点的深度,对于查找的两个点先判断在不在同一深度,不在 移到统一深度,然后在往上找
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstdio>
     5 #include <vector>
     6 using namespace std;
     7 const int Max = 10005;
     8 int t, n, first, second, root;
     9 vector<int> G[Max];
    10 int indegree[Max], depth[Max], father[Max];
    11 void inputTree()
    12 {
    13     for (int i = 0; i <= n; i++)
    14     {
    15         G[i].clear();
    16         father[i] = 0;
    17         indegree[i] = 0;
    18         depth[i] = 0;
    19     }
    20     int u, v;
    21     for (int i = 1; i < n; i++)
    22     {
    23         scanf("%d%d", &u, &v);
    24         G[u].push_back(v);
    25         indegree[v]++;
    26         father[v] = u;
    27     }
    28     scanf("%d%d", &first, &second);
    29     for (int i = 1; i <= n; i++)
    30     {
    31         if (indegree[i] == 0)
    32         {
    33             root = i;
    34             break;
    35         }
    36     }
    37 }
    38 void dfs_depth(int u, int dep)
    39 {
    40     depth[u] = dep;
    41     int Size = G[u].size();
    42     for (int i = 0; i < Size; i++)
    43     {
    44         dfs_depth(G[u][i], dep + 1);
    45     }
    46 }
    47 int find_ancestor()
    48 {
    49     while (depth[first] > depth[second])
    50     {
    51         first = father[first];
    52     }
    53     while (depth[first] < depth[second])
    54     {
    55         second = father[second];
    56     }
    57     while (first != second)  // 这样直接返回first
    58     {
    59         first = father[first];
    60         second = father[second];
    61     }
    62     return first;
    63 }
    64 int main()
    65 {
    66     scanf("%d", &t);
    67     while (t--)
    68     {
    69         scanf("%d", &n);
    70         inputTree();
    71         dfs_depth(root, 0);
    72         printf("%d
    ", find_ancestor());
    73     }
    74     return 0;
    75 }
    View Code

    tarjan + 并查集 解法:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstdio>
     5 #include <vector>
     6 using namespace std;
     7 const int Max = 10005;
     8 int t, n, first, second, root;
     9 vector<int> G[Max], querry[Max];
    10 int indegree[Max], father[Max], vis[Max];
    11 void inputTree()
    12 {
    13     for (int i = 0; i <= n; i++)
    14     {
    15         G[i].clear();
    16         querry[i].clear();
    17         father[i] = i;
    18         indegree[i] = 0;
    19         vis[i] = 0;
    20     }
    21     int u, v;
    22     for (int i = 1; i < n; i++)
    23     {
    24         scanf("%d%d", &u, &v);
    25         G[u].push_back(v);
    26         indegree[v]++;
    27     }
    28     scanf("%d%d", &first, &second);
    29     querry[first].push_back(second);
    30     querry[second].push_back(first);
    31     for (int i = 1; i <= n; i++)
    32     {
    33         if (indegree[i] == 0)
    34         {
    35             root = i;
    36             break;
    37         }
    38     }
    39 }
    40 int find_father(int x)
    41 {
    42     if (x == father[x])
    43         return x;
    44     return father[x] = find_father(father[x]);
    45 }
    46 void unionSet(int x, int y)
    47 {
    48     x = find_father(x);
    49     y = find_father(y);
    50     if (x != y)
    51         father[y] = x;
    52 }
    53 void tarjan(int x)
    54 {
    55     int Size = G[x].size();
    56     for (int i = 0; i < Size; i++)
    57     {
    58         int v = G[x][i];
    59         tarjan(v);
    60         unionSet(x, v);
    61     }
    62     vis[x] = 1;
    63     /*
    64     if (x == first && vis[second])
    65         printf("%d
    ", find_father(second));
    66     else if (x == second && vis[first])
    67         printf("%d
    ", find_father(first));
    68     */
    69     Size =  querry[x].size();
    70     for (int i = 0; i < Size; i++)
    71     {
    72         if (vis[querry[x][i]])
    73         {
    74             printf("%d
    ", find_father(querry[x][i]));
    75             return;
    76         }
    77     }
    78     
    79 }
    80 int main()
    81 {
    82     scanf("%d", &t);
    83     while (t--)
    84     {
    85         scanf("%d", &n);
    86         inputTree();
    87         tarjan(root);
    88     }
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    drf—— 序列化组件
    drf—— RESTful API规范
    drf——APIView及其内部函数/类的源码分析
    drf—— drf的安装和使用
    226翻转二叉树
    51,N皇后
    557反转字符串中的单词III
    17.电话号码的字母组合
    459重复的子字符串
    419递增子序列
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5350511.html
Copyright © 2011-2022 走看看