📌  相关文章
📜  查找给定树中每个子树的 MEX

📅  最后修改于: 2022-05-13 01:56:05.061000             🧑  作者: Mango

查找给定树中每个子树的 MEX

给定一棵由从0N – 1编号的N个节点组成的通用树,该节点以节点0为根,以及一个数组val[] ,使得每个节点的值由val[i]表示,每个节点的任务是找到其子树的MEX值。

例子:

方法:给定问题可以使用给定树上的 DFS 遍历来解决,并执行二进制搜索以在每个节点子树中找到丢失的最小正整数。请按照以下步骤解决问题:

  • 初始化一个数组,比如sol[]来存储每个节点的 MEX。
  • 从节点0执行 DFS 遍历并执行以下步骤:
    • 为向量中的每个节点存储 DFS 期间的所有节点。
    • 为递归调用中的每个节点按排序顺序合并两个向量。
    • 对排序列表应用二分查找,找到排序数组中不存在的最小非负整数值,并将当前子树的MEX值存储在数组sol[]中。
  • 完成上述步骤后,打印存储在数组sol[]中的值作为结果。

下面是上述方法的实现:

C++14
// C++ program for the above approach
 
#include 
using namespace std;
 
// Stores the edges of the tree
vector > edges;
 
// Function to add edges
void add_edge(int x, int y)
{
    edges.push_back({ x, y });
}
 
// Function to merge two sorted vectors
vector merge(vector& a,
                  vector& b)
{
    // To store the result
    vector res;
 
    int i = 0, j = 0;
    int n = a.size(), m = b.size();
 
    // Iterating both vectors
    while (i < n && j < m) {
        if (a[i] < b[j])
            res.push_back(a[i++]);
        else if (b[j] < a[i])
            res.push_back(b[j++]);
    }
 
    // Pushing remaining elements of
    // vector a
    while (i < n)
        res.push_back(a[i++]);
 
    // Pushing remaining elements of
    // vector b
    while (j < m)
        res.push_back(b[j++]);
 
    return res;
}
 
// Function to perform the DFS Traversal
// that returns the subtree of node
// in sorted manner
vector help(vector tree[], int x,
                 int p, vector& c,
                 vector& sol)
{
    vector res;
    res.push_back(c[x]);
 
    // Iterate the childrens
    for (auto i : tree[x]) {
 
        // All values of subtree
        // i in sorted manner
        if (i != p) {
            vector tmp
                = help(tree, i, x, c, sol);
            res = merge(res, tmp);
        }
    }
 
    int l = 0, r = res.size() - 1;
    int ans = res.size();
 
    // Binary search to find MEX
    while (l <= r) {
        // Find the mid
        int mid = (l + r) / 2;
 
        // Update the ranges
        if (res[mid] > mid)
            r = mid - 1;
        else {
            ans = mid + 1;
            l = mid + 1;
        }
    }
    if (res[0] != 0)
        ans = 0;
 
    // Update the MEX for the current
    // tree node
    sol[x] = ans;
 
    return res;
}
 
// Function to find MEX of each
// subtree of tree
void solve(int A, vector C)
{
    int n = A;
    vector tree[n + 1];
    for (auto i : edges) {
        tree[i[0]].push_back(i[1]);
        tree[i[1]].push_back(i[0]);
    }
    vector sol(n, 0);
 
    // Function Call
    help(tree, 0, -1, C, sol);
 
    // Print the ans for each nodes
    for (auto i : sol)
        cout << i << " ";
}
 
// Driver Code
int main()
{
    int N = 6;
    add_edge(0, 1);
    add_edge(1, 2);
    add_edge(0, 3);
    add_edge(3, 4);
    add_edge(3, 5);
 
    vector val = { 4, 3, 5, 1, 0, 2 };
    solve(N, val);
 
    return 0;
}


Javascript


输出:
6 0 0 3 1 0

时间复杂度: O(N*(N + log N))
辅助空间: O(N)