even tree Algorithm

The Even Tree Algorithm is a graph-based algorithm used to solve problems related to tree data structures, specifically the ones where the goal is to maximize the number of even sub-trees within a given tree. The algorithm works by analyzing the nodes within the tree, and their connections, to determine how the tree can be optimally divided into smaller sub-trees with an even number of nodes in each sub-tree. This algorithm is particularly useful in competitive programming and solving graph theory problems where the objective is to maximize or minimize some parameter by dividing the tree into even sub-trees. The basic idea behind the Even Tree Algorithm is to traverse the given tree either using Depth First Search (DFS) or Breadth First Search (BFS) and count the number of nodes in each sub-tree rooted at a certain node. Then, for each node, the algorithm checks if the count of nodes in the sub-tree is even. If the count is even, it means that the subtree rooted at that node can be safely removed from the tree without violating the evenness constraint. This removal is performed by cutting the edge that connects the sub-tree to the parent node. The process is repeated until there are no more sub-trees with an even number of nodes that can be removed. The result is the maximum number of even sub-trees that can be created from the given tree, which is also the number of edges that were cut during the process.
"""
You are given a tree(a simple connected graph with no cycles). The tree has N
nodes numbered from 1 to N and is rooted at node 1.

Find the maximum number of edges you can remove from the tree to get a forest
such that each connected component of the forest contains an even number of
nodes.

Constraints
2 <= 2 <= 100

Note: The tree input will be such that it can always be decomposed into
components containing an even number of nodes.
"""
# pylint: disable=invalid-name
from collections import defaultdict


def dfs(start):
    """DFS traversal"""
    # pylint: disable=redefined-outer-name
    ret = 1
    visited[start] = True
    for v in tree.get(start):
        if v not in visited:
            ret += dfs(v)
    if ret % 2 == 0:
        cuts.append(start)
    return ret


def even_tree():
    """
    2 1
    3 1
    4 3
    5 2
    6 1
    7 2
    8 6
    9 8
    10 8
    On removing edges (1,3) and (1,6), we can get the desired result 2.
    """
    dfs(1)


if __name__ == "__main__":
    n, m = 10, 9
    tree = defaultdict(list)
    visited = {}
    cuts = []
    count = 0
    edges = [(2, 1), (3, 1), (4, 3), (5, 2), (6, 1), (7, 2), (8, 6), (9, 8), (10, 8)]
    for u, v in edges:
        tree[u].append(v)
        tree[v].append(u)
    even_tree()
    print(len(cuts) - 1)

LANGUAGE:

DARK MODE: