1143. Lowest Common Ancestor (30)

本文介绍了一种高效算法来解决二叉搜索树中两个节点的最低公共祖先(LCA)问题。通过预处理二叉搜索树的前序遍历序列,并结合中序遍历的性质,快速定位LCA。此外,还提供了完整的代码实现和样例输入输出。

1143. Lowest Common Ancestor (30)
时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B
判题程序 Standard 作者 CHEN, Yue

The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.
A binary search tree (BST) is recursively defined as a binary tree which has the following properties:
The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
Both the left and right subtrees must also be binary search trees.
Given any two nodes in a BST, you are supposed to find their LCA.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers: M (<= 1000), the number of pairs of nodes to be tested; and N (<= 10000), the number of keys in the BST, respectively. In the second line, N distinct integers are given as the preorder traversal sequence of the BST. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.
Output Specification:
For each given pair of U and V, print in a line “LCA of U and V is A.” if the LCA is found and A is the key. But if A is one of U and V, print “X is an ancestor of Y.” where X is A and Y is the other node. If U or V is not found in the BST, print in a line “ERROR: U is not found.” or “ERROR: V is not found.” or “ERROR: U and V are not found.”.
Sample Input:
6 8
6 3 1 2 5 4 8 7
2 5
8 7
1 9
12 -3
0 8
99 99
Sample Output:
LCA of 2 and 5 is 3.
8 is an ancestor of 7.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.

注意点:不能直接进行插入建树,会超时…

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <stack>
#include <set>
using namespace std;
const int Maxn = 10000;

typedef struct node {
    int data;
    struct node* lchild;
    struct node* rchild;
    node() { lchild = rchild = nullptr; }
}TNode, *PTNode;


int M, N;
set<int> keys;
int pre[Maxn], in[Maxn];

//void Insert(PTNode  & root, int data) {
//  if (!root) {
//      root = new TNode;
//      root->data = data;
//      return;
//  }
//  else if (root->data < data) Insert(root->rchild, data);
//  else if (root->data > data) Insert(root->lchild, data);
//}

PTNode CreateBST(int pre[], int in[], int p_l, int p_r, int i_l, int i_r) {
    if (p_l > p_r) return nullptr;
    PTNode root = new TNode;
    root->data = pre[p_l];

    int idx = i_l;
    while (idx < i_r && in[idx] != pre[p_l])++idx;
    root->lchild = CreateBST(pre, in, p_l + 1, p_l + idx - i_l - 1, i_l, idx - 1);
    root->rchild = CreateBST(pre, in, p_l + idx - i_l + 1, p_r, idx + 1, i_r);
    return root;
}


int findLCA(PTNode root, int e1, int e2, bool &ans1, bool &ans2) {
    if (e1 < root->data && e2 < root->data)  return findLCA(root->lchild, e1, e2, ans1, ans2);//如果当前根节点均小于查询的两个节点,则最小近公共祖先在左子树
    else if (e1 > root->data && e2 > root->data)  return findLCA(root->rchild, e1, e2, ans1, ans2);//如果当前根节点均大于查询的两个节点,则最小近公共祖先在右子树
    else if (e1 > root->data && e2 < root->data || e1 < root->data && e2 > root->data) return root->data;//如果一大一小,那么当前节点肯定是其最近公共祖先
    else { //否则其中一个值一定是另一个值的祖先
        if (e1 != root->data)ans2 = true;
        else ans1 = true;
        return root->data;
    }
}


int main()
{
#ifdef _DEBUG
    freopen("data.txt", "r+", stdin);
#endif

    std::ios::sync_with_stdio(false);
    int data;
    cin >> M >> N;
    for (int i = 0; i<N; ++i) {
        cin >> data;
        in[i] = pre[i] = data;
        keys.insert(data);
    }
    sort(in, in + N);
    PTNode root = CreateBST(pre, in, 0, N - 1, 0, N - 1);

    while (M--) {
        bool f1flag = true, f2flag = true;
        int e1, e2;
        cin >> e1 >> e2;
        if (keys.find(e1) == keys.end()) f1flag = false;
        if (keys.find(e2) == keys.end()) f2flag = false;

        if (f1flag == false || f2flag == false) {
            if (f1flag && !f2flag) cout << "ERROR: " << e2 << " is not found.\n";
            else if (!f1flag && f2flag) cout << "ERROR: " << e1 << " is not found.\n";
            else cout << "ERROR: " << e1 << " and " << e2 << " are not found.\n";
            continue;
        }
        bool ans1 = false, ans2 = false;
        int LCAD = findLCA(root, e1, e2, ans1, ans2);
        if (ans1)cout << e1 << " is an ancestor of " << e2 << ".\n";
        else if (ans2) cout << e2 << " is an ancestor of " << e1 << ".\n";
        else cout << "LCA of " << e1 << " and " << e2 << " is " << LCAD << ".\n";
    }

    return 0;
}
内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
以下是C#中二叉树的lowest common ancestor的源代码: ```csharp using System; public class Node { public int value; public Node left; public Node right; public Node(int value) { this.value = value; this.left = null; this.right = null; } } public class BinaryTree { public Node root; public BinaryTree() { this.root = null; } public Node LowestCommonAncestor(Node node, int value1, int value2) { if (node == null) { return null; } if (node.value == value1 || node.value == value2) { return node; } Node left = LowestCommonAncestor(node.left, value1, value2); Node right = LowestCommonAncestor(node.right, value1, value2); if (left != null && right != null) { return node; } return (left != null) ? left : right; } } public class Program { public static void Main() { BinaryTree tree = new BinaryTree(); tree.root = new Node(1); tree.root.left = new Node(2); tree.root.right = new Node(3); tree.root.left.left = new Node(4); tree.root.left.right = new Node(5); tree.root.right.left = new Node(6); tree.root.right.right = new Node(7); Node lca = tree.LowestCommonAncestor(tree.root, 4, 5); Console.WriteLine("Lowest Common Ancestor of 4 and 5: " + lca.value); lca = tree.LowestCommonAncestor(tree.root, 4, 6); Console.WriteLine("Lowest Common Ancestor of 4 and 6: " + lca.value); lca = tree.LowestCommonAncestor(tree.root, 3, 4); Console.WriteLine("Lowest Common Ancestor of 3 and 4: " + lca.value); lca = tree.LowestCommonAncestor(tree.root, 2, 4); Console.WriteLine("Lowest Common Ancestor of 2 and 4: " + lca.value); } } ``` 在上面的代码中,我们定义了一个Node类和一个BinaryTree类。我们使用BinaryTree类来创建二叉树,并实现了一个LowestCommonAncestor方法来计算二叉树中给定两个节点的最近公共祖先。 在LowestCommonAncestor方法中,我们首先检查给定节点是否为null或与给定值之一匹配。如果是,则返回该节点。否则,我们递归地在左子树和右子树上调用LowestCommonAncestor方法,并检查它们的返回值。如果左子树和右子树的返回值都不为null,则当前节点是它们的最近公共祖先。否则,我们返回非null的那个子树的返回值。 在Main方法中,我们创建了一个二叉树,并测试了LowestCommonAncestor方法的几个不同输入。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值