Disjoint Set Union on trees | Set 1

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.

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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++

 // CPP code to find maximum subtree such // that all nodes are even in weight #include    using namespace std;    #define N 100010    // Structure for Edge struct 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 root int Root(int idx) {     int i = idx;            while(i != id[i])          id[i] = id[id[i]], i = id[i];            return i; }    // Function to find Union 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 Union void 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 tree int 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 code int 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);        // 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);        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

 // Java code to find maximum subtree such // that all nodes are even in weight class GFG { static int N = 100010;    // Structure for Edge static 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 root static int Root(int idx) {     int i = idx;            while(i != id[i])     {          id[i] = id[id[i]];         i = id[i];     }     return i; }    // Function to find Union static 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 Union static 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 tree static 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 code public 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

C#

 // C# code to find maximum subtree such // that all nodes are even in weight using System;    class GFG { static int N = 100010;    // Structure for Edge public 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 root static int Root(int idx) {     int i = idx;            while(i != id[i])     {          id[i] = id[id[i]];         i = id[i];     }     return i; }    // Function to find Union static 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 Union static 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 tree static 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 code public 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

Output:

Maximum size of the subtree with even weighted nodes = 4

My Personal Notes arrow_drop_up The time hast cometh

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : Rajput-Ji, princi singh

Article Tags :

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.