Disjoint Set Union on trees | Set 1 - GeeksforGeeks

29 Jun, 2021
Given a tree and weights of nodes. Weights are non-negative integers. Task is to find maximum size of a subtree of a given tree such that all nodes are even in weights.Prerequisite : Disjoint Set Union
Examples : 
Input : Number of nodes = 7
        Weights of nodes = 1 2 6 4 2 0 3
        Edges = (1, 2), (1, 3), (2, 4), 
                (2, 5), (4, 6), (6, 7)
Output : Maximum size of the subtree 
with even weighted nodes = 4 
Explanation : 
Subtree of nodes {2, 4, 5, 6} gives the maximum size.

Input : Number of nodes = 6
        Weights of nodes = 2 4 0 2 2 6
        Edges = (1, 2), (2, 3), (3, 4), 
                (4, 5), (1, 6)
Output : Maximum size of the subtree
with even weighted nodes = 6
Explanation : 
The given tree gives the maximum size.
Approach: We can find solution by simply running DFS on tree. DFS solution gives us answer in O(n). But, how can we use DSU for this problem? We first iterate through all edges. If both nodes are even in weights, we make union of them. Set of nodes with maximum size is the answer. If we use union-find with path compression then time complexity is O(n).
Below is the implementation of above approach :  
C++
Java
Python3
C#
Javascript
// CPP code to find maximum subtree such// that all nodes are even in weight#include<bits/stdc++.h> using namespace std; #define N 100010 // Structure for Edgestruct Edge{    int u, v;}; /*    'id': stores parent of a node.    'sz': stores size of a DSU tree.*/int id[N], sz[N]; // Function to assign rootint Root(int idx){    int i = idx;         while(i != id[i])        id[i] = id[id[i]], i = id[i];         return i;} // Function to find Unionvoid Union(int a, int b){    int i = Root(a), j = Root(b);         if (i != j)    {        if(sz[i] >= sz[j])        {            id[j] = i, sz[i] += sz[j];            sz[j] = 0;        }        else        {            id[i] = j, sz[j] += sz[i];            sz[i] = 0;        }    }} // Utility function for Unionvoid UnionUtil(struct Edge e[], int W[], int q){     for(int i = 0; i < q; i++)    {        // Edge between 'u' and 'v'        int u, v;        u = e[i].u, v = e[i].v;         // 0-indexed nodes        u--, v--;         // If weights of both 'u' and 'v'        // are even then we make union of them.        if(W[u] % 2 == 0 && W[v] % 2 == 0)                    Union(u,v);    }} // Function to find maximum// size of DSU treeint findMax(int n, int W[]){    int maxi = 0;    for(int i = 1; i <= n; i++)        if(W[i] % 2 == 0)            maxi = max(maxi, sz[i]);                   return maxi;} // Driver codeint main(){    /*        Nodes are 0-indexed in this code        So we have to make necessary changes        while taking inputs    */     // Weights of nodes    int W[] = {1, 2, 6, 4, 2, 0, 3};     // Number of nodes in a tree    int n = sizeof(W) / sizeof(W[0]);     // Initializing every node as    // a tree with single node.    for(int i = 0; i < n; i++)            id[i] = i, sz[i] = 1;     Edge e[] = {{1, 2}, {1, 3}, {2, 4},                {2, 5}, {4, 6}, {6, 7}};     int q = sizeof(e) / sizeof(e[0]);     UnionUtil(e, W, q);     // Find maximum size of DSU tree.    int maxi = findMax(n, W);     printf("Maximum size of the subtree with ");    printf("even weighted nodes = %d\n", maxi);         return 0;}
// Java code to find maximum subtree such// that all nodes are even in weightclass GFG{static int N = 100010; // Structure for Edgestatic class Edge{    int u, v;     public Edge(int u, int v)    {        this.u = u;        this.v = v;    }} /*'id': stores parent of a node.'sz': stores size of a DSU tree.*/static int []id = new int[N];static int []sz = new int[N]; // Function to assign rootstatic int Root(int idx){    int i = idx;         while(i != id[i])    {        id[i] = id[id[i]];        i = id[i];    }    return i;} // Function to find Unionstatic void Union(int a, int b){    int i = Root(a), j = Root(b);         if (i != j)    {        if(sz[i] >= sz[j])        {            id[j] = i;            sz[i] += sz[j];            sz[j] = 0;        }        else        {            id[i] = j;            sz[j] += sz[i];            sz[i] = 0;        }    }} // Utility function for Unionstatic void UnionUtil(Edge e[], int W[], int q){    for(int i = 0; i < q; i++)    {        // Edge between 'u' and 'v'        int u, v;        u = e[i].u;        v = e[i].v;         // 0-indexed nodes        u--;        v--;         // If weights of both 'u' and 'v'        // are even then we make union of them.        if(W[u] % 2 == 0 && W[v] % 2 == 0)            Union(u, v);    }} // Function to find maximum// size of DSU treestatic int findMax(int n, int W[]){    int maxi = 0;    for(int i = 1; i < n; i++)        if(W[i] % 2 == 0)            maxi = Math.max(maxi, sz[i]);                 return maxi;} // Driver codepublic static void main(String[] args){    /*    Nodes are 0-indexed in this code    So we have to make necessary changes    while taking inputs    */     // Weights of nodes    int W[] = {1, 2, 6, 4, 2, 0, 3};     // Number of nodes in a tree    int n = W.length;     // Initializing every node as    // a tree with single node.    for(int i = 0; i < n; i++)    {        id[i] = i;        sz[i] = 1;    }     Edge e[] = {new Edge(1, 2), new Edge(1, 3),                new Edge(2, 4), new Edge(2, 5),                new Edge(4, 6), new Edge(6, 7)};     int q = e.length;     UnionUtil(e, W, q);     // Find maximum size of DSU tree.    int maxi = findMax(n, W);     System.out.printf("Maximum size of the subtree with ");    System.out.printf("even weighted nodes = %d\n", maxi);}} // This code is contributed by Rajput-Ji
# Python3 code to find maximum subtree such# that all nodes are even in weightN = 100010  # Structure for Edgeclass Edge:         def __init__(self, u, v):        self.u = u        self.v = v     '''    'id': stores parent of a node.    'sz': stores size of a DSU tree.''' id = [0 for i in range(N)]sz = [0 for i in range(N)];  # Function to assign rootdef Root(idx):     i = idx;          while(i != id[i]):                 id[i] = id[id[i]]        i = id[i];          return i; # Function to find Uniondef Union(a, b):     i = Root(a)    j = Root(b);          if (i != j):             if(sz[i] >= sz[j]):                     id[j] = i            sz[i] += sz[j];            sz[j] = 0;        else:                     id[i] = j            sz[j] += sz[i];            sz[i] = 0;         # Utility function for Uniondef UnionUtil( e, W, q):         for i in range(q):               # Edge between 'u' and 'v'        u = e[i].u        v = e[i].v          # 0-indexed nodes        u -= 1        v -= 1          # If weights of both 'u' and 'v'        # are even then we make union of them.        if(W[u] % 2 == 0 and W[v] % 2 == 0):            Union(u, v);     # Function to find maximum# size of DSU treedef findMax(n, W):     maxi = 0         for i in range(1, n):             if(W[i] % 2 == 0):            maxi = max(maxi, sz[i]);                    return maxi; # Driver codeif __name__=='__main__':         '''        Nodes are 0-indexed in this code        So we have to make necessary changes        while taking inputs    '''      # Weights of nodes    W = [1, 2, 6, 4, 2, 0, 3]      # Number of nodes in a tree    n = len(W)      # Initializing every node as    # a tree with single node.    for i in range(n):                 id[i] = i            sz[i] = 1;      e = [Edge(1, 2), Edge(1, 3), Edge(2, 4),                Edge(2, 5), Edge(4, 6), Edge(6, 7)]      q = len(e)      UnionUtil(e, W, q);      # Find maximum size of DSU tree.    maxi = findMax(n, W);      print("Maximum size of the subtree with ", end='');    print("even weighted nodes =", maxi);      # This code is contributed by rutvik_56
// C# code to find maximum subtree such// that all nodes are even in weightusing System; class GFG{static int N = 100010; // Structure for Edgepublic class Edge{    public int u, v;     public Edge(int u, int v)    {        this.u = u;        this.v = v;    }} /*'id': stores parent of a node.'sz': stores size of a DSU tree.*/static int []id = new int[N];static int []sz = new int[N]; // Function to assign rootstatic int Root(int idx){    int i = idx;         while(i != id[i])    {        id[i] = id[id[i]];        i = id[i];    }    return i;} // Function to find Unionstatic void Union(int a, int b){    int i = Root(a), j = Root(b);         if (i != j)    {        if(sz[i] >= sz[j])        {            id[j] = i;            sz[i] += sz[j];            sz[j] = 0;        }        else        {            id[i] = j;            sz[j] += sz[i];            sz[i] = 0;        }    }} // Utility function for Unionstatic void UnionUtil(Edge []e, int []W, int q){    for(int i = 0; i < q; i++)    {        // Edge between 'u' and 'v'        int u, v;        u = e[i].u;        v = e[i].v;         // 0-indexed nodes        u--;        v--;         // If weights of both 'u' and 'v'        // are even then we make union of them.        if(W[u] % 2 == 0 && W[v] % 2 == 0)            Union(u, v);    }} // Function to find maximum// size of DSU treestatic int findMax(int n, int []W){    int maxi = 0;    for(int i = 1; i < n; i++)        if(W[i] % 2 == 0)            maxi = Math.Max(maxi, sz[i]);                 return maxi;} // Driver codepublic static void Main(String[] args){    /*    Nodes are 0-indexed in this code    So we have to make necessary changes    while taking inputs    */     // Weights of nodes    int []W = {1, 2, 6, 4, 2, 0, 3};     // Number of nodes in a tree    int n = W.Length;     // Initializing every node as    // a tree with single node.    for(int i = 0; i < n; i++)    {        id[i] = i;        sz[i] = 1;    }     Edge []e = {new Edge(1, 2), new Edge(1, 3),                new Edge(2, 4), new Edge(2, 5),                new Edge(4, 6), new Edge(6, 7)};     int q = e.Length;     UnionUtil(e, W, q);     // Find maximum size of DSU tree.    int maxi = findMax(n, W);     Console.Write("Maximum size of the subtree with ");    Console.WriteLine("even weighted nodes = {0}\n", maxi);}} // This code is contributed by Princi Singh
<script> // Javascript code to find maximum subtree such// that all nodes are even in weightlet N = 100010; /*'id': stores parent of a node.'sz': stores size of a DSU tree.*/let id = new Array(N);let sz = new Array(N); // Function to assign rootfunction Root(idx){    let i = idx;     while(i != id[i])    {        id[i] = id[id[i]];        i = id[i];    }    return i;} // Function to find Unionfunction Union(a, b){    let i = Root(a), j = Root(b);     if (i != j)    {        if (sz[i] >= sz[j])        {            id[j] = i;            sz[i] += sz[j];            sz[j] = 0;        }        else        {            id[i] = j;            sz[j] += sz[i];            sz[i] = 0;        }    }} // Utility function for Unionfunction UnionUtil(e, W, q){    for(let i = 0; i < q; i++)    {                 // Edge between 'u' and 'v'        let u, v;        u = e[i][0];        v = e[i][1];         // 0-indexed nodes        u--;        v--;         // If weights of both 'u' and 'v'        // are even then we make union of them.        if (W[u] % 2 == 0 && W[v] % 2 == 0)            Union(u, v);    }} // Function to find maximum// size of DSU treefunction findMax(n, W){    let maxi = 0;    for(let i = 1; i < n; i++)        if (W[i] % 2 == 0)            maxi = Math.max(maxi, sz[i]);     return maxi;} // Driver code /*Nodes are 0-indexed in this codeSo we have to make necessary changeswhile taking inputs*/ // Weights of nodeslet W = [ 1, 2, 6, 4, 2, 0, 3 ]; // Number of nodes in a treelet n = W.length; // Initializing every node as// a tree with single node.for(let i = 0; i < n; i++){    id[i] = i;    sz[i] = 1;} let e = [ [ 1, 2 ], [ 1, 3 ],          [ 2, 4 ], [ 2, 5 ],          [ 4, 6 ], [ 6, 7 ] ];let q = e.length; UnionUtil(e, W, q); // Find maximum size of DSU tree.let maxi = findMax(n, W); document.write("Maximum size of the subtree with ");document.write("even weighted nodes = " + maxi); // This code is contributed by divyesh072019 </script>
Maximum size of the subtree with even weighted nodes = 4
 
Rajput-Ji
princi singh
rutvik_56
itsok
divyesh072019
Binary Trees Quiz
DFS
union-find
Bit Magic
Tree
Bit Magic
DFS
Tree
union-find
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Cyclic Redundancy Check and Modulo-2 Division
Little and Big Endian Mystery
Program to find whether a given number is power of 2
Binary representation of a given number
Bits manipulation (Important tactics)
Tree Traversals (Inorder, Preorder and Postorder)
Binary Tree | Set 1 (Introduction)
Level Order Binary Tree Traversal
AVL Tree | Set 1 (Insertion)
Inorder Tree Traversal without Recursion