Even size subtree in n-ary tree

Given an n-ary tree of n vertices and n-1 edges. The tree is given in the form of adjacency list. Find number of subtrees of even size in given tree.

Examples:

Input : 
                1
               / \
              2   3
             / \   \
            4   5   6
               / \
              7   8

Output : 2
Subtree rooted at 1 and 3 are of even size. 

Input :
                1
               / \
              2   3
            / | \   \
           4  5  6   7
            / | \
           8  9 10
    
Output : 3
Subtree rooted at 1, 3 and 5 are of even size.

A simple solution is to perform dfs starting from every node and find size of subtree rooted at that node. If size is even increment count. Time complexity of above solution is O(n2).



A better solution is to perform single dfs on given tree. The idea is to first find recursively size of subtree of all childeren nodes, then find size of subtree rooted at current node by taking sum of size of children node subtrees and increment count if size is even.

Below is the implementation of above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to find number of subtrees of even size.
#include <bits/stdc++.h>
using namespace std;
  
// DFS function to traverse the tree and find
// number of even size subtree.
int dfs(vector<int> adj[], int n, int v, int& ans)
{
    // Size of subtree is minimum possible 1 for
    // leaf node.
    int size = 1;
  
    // Find size of subtree rooted at children nodes
    // and add the size to current subtree size.
    for (auto ele : adj[v]) {
        size += dfs(adj, n, ele, ans);
    }
  
    // If size is even then increment count.
    if (size % 2 == 0)
        ans++;
}
  
// Driver code
int main()
{
    int n;
    n = 10;
  
    vector<int> adj[n + 1];
    /*
                1
               / \
              2   3
             / \   \
            4   5   6
               / \
              7   8
    */
    adj[1].push_back(2);
    adj[1].push_back(3);
    adj[2].push_back(4);
    adj[2].push_back(5);
    adj[3].push_back(6);
    adj[5].push_back(7);
    adj[5].push_back(8);
  
    /*
                 1
                / \
               2   3
             / | \  \
            4  5  6  7
             / | \
            8  9 10
    */
    /*adj[1].push_back(2);
    adj[1].push_back(3);
    adj[2].push_back(4);
    adj[2].push_back(5);
    adj[2].push_back(6);
    adj[3].push_back(7);
    adj[5].push_back(8);
    adj[5].push_back(9);
    adj[5].push_back(10);
    */
    int ans = 0;
  
    dfs(adj, n, 1, ans);
  
    cout << ans;
    return 0;
}

chevron_right


Output: 2

Time Complexity: O(n)
Auxiliary Space: O(1)



My Personal Notes arrow_drop_up

A Programmer and A Machine learning Enthusiast

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.




Article Tags :
Practice Tags :


Be the First to upvote.


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