Find number of edges that can be broken in a tree such that Bitwise OR of resulting two trees are equal in C++


Concept

With respect of a given tree with m nodes and a number associated with every node, we canbreak any tree edge which will result in the formation of 2 new trees. Here, we have to count the number of edges in this way so that the Bitwise OR of the nodes present in the two trees constructed after breaking that edge are equal. It should be noted that the value ofevery node is ≤ 10^6.

Input

values[]={1, 3, 1, 3}
     1
   / | \
  2 3 4

Output

2

Here, the edge between 1 and 2 can be broken, the Bitwise OR of the resulting two trees will be 3.

In similar way, the edge between 1 and 4 can also be broken.

Method

Here, the above-mentioned problem can be solved implementing simple DFS(Depth First Search). Because the value of the nodes are ≤ 10^6, it can be represented implementing 22 binary bits. As a result of this, the Bitwise OR of the value of the nodes can also be represented in 22 binary bits. Here, the method is to determine the number of times each bit is set in all the values of a sub-tree. For each edge we will verify that with respect of each bit from 0 to 21 the numbers with that particular bit as set are either zero in both the resulting trees or higher than zero in both the resulting trees and if it has been seen that the condition is satisfied for all the bits then that edge is counted in the result.

Example

 Live Demo

// C++ implementation of the approach
#include<bits/stdc++.h>
using namespace std;
int m1[1000],x1[22];
// Uses array to store the number of times each bit
// is set in all the values of a subtree
int a1[1000][22];
vector<vector<int>> g;
int ans1 = 0;
// Shows function to perform simple DFS
void dfs(int u1, int p1){
   for (int i=0;i<g[u1].size();i++) {
      int v1 = g[u1][i];
      if (v1 != p1) {
         dfs(v1, u1);
         // Determining 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++)
            a1[u1][i] += a1[v1][i];
         }
      }
      // Verifying 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 pp1 = 0;
      for (int i = 0; i < 22; i++) {
         if (!((a1[u1][i] > 0 && x1[i] - a1[u1][i] > 0)
            || (a1[u1][i] == 0 && x1[i] == 0))) {
         pp1 = 1;
         break;
      }
   }
   if (pp1 == 0)
   ans1++;
}
// Driver code
int main(){
   // Number of nodes
   int n1 = 4;
   // int n1 = 5;
   // Uses ArrayList to store the tree
   g.resize(n1+1);
   // Uses array to store the value of nodes
   m1[1] = 1;
   m1[2] = 3;
   m1[3] = 1;
   m1[4] = 3;
   /* m1[1] = 2;
   m1[2] = 3;
   m1[3] = 32;
   m1[4] = 43;
   m1[5] = 8;*/
   //Uses array to store the number of times each bit
   // is set in all the values in complete tree
   for (int i = 1; i <= n1; i++) {
      int y1 = m1[i];
      int k1 = 0;
      // Determining the set bits in the value of node i
      while (y1 != 0) {
         int p1 = y1 % 2;
         if (p1 == 1) {
            x1[k1]++;
            a1[i][k1]++;
         }
         y1 = y1 / 2;
         k1++;
      }
   }
   // 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);
   //g[1].push_back(5);
   //g[5].push_back(1);
   dfs(1, 0);
   cout<<(ans1);
}

Output

2

Updated on: 25-Jul-2020

211 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements