📜  查找可以在树中断开的边数,使得生成的两棵树的按位或相等

📅  最后修改于: 2021-09-22 10:31:00             🧑  作者: Mango

给定一棵树,有 n 个节点,每个节点都有一个数字。我们可以打破树的任何边缘,这将导致形成 2 棵新树。我们必须计算边的数量,使得在打破该边后形成的两棵树中存在的节点的按位或是相等的。每个节点的值≤ 10 6
例子:

Input: values[]={2, 3, 32, 43, 8}
         1
        / \
       2   3
      /     \
     4       5
Output: 1
If we break the edge between 2 and 4 then the Bitwise OR 
of both the resulting tree will be 43.

Input: values[]={1, 3, 2, 3}
        1
      / | \
     2  3  4
Output: 2
The edge between 1 and 2 can be broken,the Bitwise OR 
of the resulting two trees will be 3.
Similarly, the edge between 1 and 4 can also be broken.

方法:这个问题可以使用简单的 DFS 来解决。由于节点的值≤ 10 6 ,因此可以使用22 个二进制位来表示。节点值的按位或也可以用 22 个二进制位表示。该方法是找出在子树的所有值中设置每个位的次数。对于每条边,我们将检查从 0 到 21 的每一位,具有该特定位的数字在两个结果树中都为零或在两个结果树中都大于零,并且如果条件满足所有位该边缘被计入结果。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include
using namespace std;
 
    int m[1000],x[22];
     
    // Array to store the number of times each bit
    // is set in all the values of a subtree
    int a[1000][22];
     
    vector> g;
    int ans = 0;
 
    // Function to perform simple DFS
    void dfs(int u, int p)
    {
        for (int i=0;i 0 && x[i] - a[u][i] > 0)
                || (a[u][i] == 0 && x[i] == 0))) {
                pp = 1;
                break;
            }
        }
        if (pp == 0)
            ans++;
    }
 
    // Driver code
    int main()
    {
 
        // Number of nodes
        int n = 4;
 
        // ArrayList to store the tree
        g.resize(n+1);
 
        // Array to store the value of nodes
        m[1] = 1;
        m[2] = 3;
        m[3] = 2;
        m[4] = 3;
 
 
        // Array to store the number of times each bit
        // is set in all the values in complete tree
         
        for (int i = 1; i <= n; i++) {
            int y = m[i];
            int k = 0;
 
            // Finding the set bits in the value of node i
            while (y != 0) {
                int p = y % 2;
                if (p == 1) {
                    x[k]++;
                    a[i][k]++;
                }
                y = y / 2;
                k++;
            }
        }
 
        // push_back edges
        g[1].push_back(2);
        g[2].push_back(1);
        g[1].push_back(3);
        g[3].push_back(1);
        g[1].push_back(4);
        g[4].push_back(1);
        dfs(1, 0);
        cout<<(ans);
}
//contributed by Arnab Kundu


Java
// Java implementation of the approach
import java.util.*;
public class GFG {
    static int m[], a[][], x[];
    static ArrayList g[];
    static int ans = 0;
 
    // Function to perform simple DFS
    static void dfs(int u, int p)
    {
        for (int v : g[u]) {
            if (v != p) {
                dfs(v, u);
 
                // Finding the number of times each bit is set
                // in all the values of a subtree rooted at v
                for (int i = 0; i < 22; i++)
                    a[u][i] += a[v][i];
            }
        }
 
        // Checking for each bit whether the numbers
        // with that particular bit as set are
        // either zero in both the resulting trees or
        // greater than zero in both the resulting trees
        int pp = 0;
        for (int i = 0; i < 22; i++) {
            if (!((a[u][i] > 0 && x[i] - a[u][i] > 0)
                  || (a[u][i] == 0 && x[i] == 0))) {
                pp = 1;
                break;
            }
        }
        if (pp == 0)
            ans++;
    }
 
    // Driver code
    public static void main(String args[])
    {
 
        // Number of nodes
        int n = 4;
 
        // ArrayList to store the tree
        g = new ArrayList[n + 1];
 
        // Array to store the value of nodes
        m = new int[n + 1];
        m[1] = 1;
        m[2] = 3;
        m[3] = 2;
        m[4] = 3;
 
        // Array to store the number of times each bit
        // is set in all the values of a subtree
        a = new int[n + 1][22];
 
        // Array to store the number of times each bit
        // is set in all the values in complete tree
        x = new int[22];
        for (int i = 1; i <= n; i++) {
            g[i] = new ArrayList<>();
            int y = m[i];
            int k = 0;
 
            // Finding the set bits in the value of node i
            while (y != 0) {
                int p = y % 2;
                if (p == 1) {
                    x[k]++;
                    a[i][k]++;
                }
                y = y / 2;
                k++;
            }
        }
 
        // Add edges
        g[1].add(2);
        g[2].add(1);
        g[1].add(3);
        g[3].add(1);
        g[1].add(4);
        g[4].add(1);
        dfs(1, 0);
        System.out.println(ans);
    }
}


Python3
# Python3 implementation of the approach
m, x = [0] * 1000, [0] * 22
 
# Array to store the number of times each bit
# is set in all the values of a subtree
a = [[0 for i in range(22)]
        for j in range(1000)]
ans = 0
 
# Function to perform simple DFS
def dfs(u, p):
 
    global ans
    for i in range(0, len(g[u])):
        v = g[u][i]
        if v != p:
            dfs(v, u)
 
            # Finding the number of times
            # each bit is set in all the
            # values of a subtree rooted at v
            for i in range(0, 22):
                a[u][i] += a[v][i]
 
    # Checking for each bit whether the numbers
    # with that particular bit as set are
    # either zero in both the resulting trees or
    # greater than zero in both the resulting trees
    pp = 0
    for i in range(0, 22):
        if (not((a[u][i] > 0 and
                 x[i] - a[u][i] > 0)
            or (a[u][i] == 0 and x[i] == 0))):
            pp = 1
            break
         
    if pp == 0:
        ans += 1
 
# Driver code
if __name__ == "__main__":
 
    # Number of nodes
    n = 4
 
    # ArrayList to store the tree
    g = [[] for i in range(n+1)]
 
    # Array to store the value of nodes
    m[1] = 1
    m[2] = 3
    m[3] = 2
    m[4] = 3
 
    # Array to store the number of times
    # each bit is set in all the values
    # in complete tree
    for i in range(1, n+1):
        y, k = m[i], 0
 
        # Finding the set bits in the
        # value of node i
        while y != 0:
            p = y % 2
            if p == 1:
                x[k] += 1
                a[i][k] += 1
             
            y = y // 2
            k += 1
         
    # append edges
    g[1].append(2)
    g[2].append(1)
    g[1].append(3)
    g[3].append(1)
    g[1].append(4)
    g[4].append(1)
    dfs(1, 0)
    print(ans)
 
# This code is contributed by Rituraj Jain


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
    static int []m;
    static int [,]a;
    static int []x;
    static List []g;
    static int ans = 0;
 
    // Function to perform simple DFS
    static void dfs(int u, int p)
    {
        foreach (int v in g[u])
        {
            if (v != p)
            {
                dfs(v, u);
 
                // Finding the number of times each bit is set
                // in all the values of a subtree rooted at v
                for (int i = 0; i < 22; i++)
                    a[u,i] += a[v,i];
            }
        }
 
        // Checking for each bit whether the numbers
        // with that particular bit as set are
        // either zero in both the resulting trees or
        // greater than zero in both the resulting trees
        int pp = 0;
        for (int i = 0; i < 22; i++)
        {
            if (!((a[u,i] > 0 && x[i] - a[u,i] > 0)
                || (a[u,i] == 0 && x[i] == 0)))
            {
                pp = 1;
                break;
            }
        }
        if (pp == 0)
            ans++;
    }
 
    // Driver code
    public static void Main(String []args)
    {
 
        // Number of nodes
        int n = 4;
 
        // ArrayList to store the tree
        g = new List[n + 1];
 
        // Array to store the value of nodes
        m = new int[n + 1];
        m[1] = 1;
        m[2] = 3;
        m[3] = 2;
        m[4] = 3;
 
        // Array to store the number of times each bit
        // is set in all the values of a subtree
        a = new int[n + 1,22];
 
        // Array to store the number of times each bit
        // is set in all the values in complete tree
        x = new int[22];
        for (int i = 1; i <= n; i++)
        {
            g[i] = new List();
            int y = m[i];
            int k = 0;
 
            // Finding the set bits in the value of node i
            while (y != 0)
            {
                int p = y % 2;
                if (p == 1)
                {
                    x[k]++;
                    a[i,k]++;
                }
                y = y / 2;
                k++;
            }
        }
 
        // Add edges
        g[1].Add(2);
        g[2].Add(1);
        g[1].Add(3);
        g[3].Add(1);
        g[1].Add(4);
        g[4].Add(1);
        dfs(1, 0);
        Console.WriteLine(ans);
    }
}
 
// This code contributed by Rajput-Ji


Javascript


输出:
2

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程