Sort by

recency

|

284 Discussions

|

  • + 0 comments

    it's just not best

    def evenForest(t_nodes, t_edges, t_from, t_to):
        kq = 0
        d = {}
        r = {}
        p = []
    
        for i in range(t_edges):
            if t_to[i] not in d:
                d[t_to[i]] = [t_from[i]]
                r[t_to[i]] = 1
            else:
                d[t_to[i]].append(t_from[i])
    
        for i in d:
            j = 0
            while j < len(d[i]):
                if d[i][j] not in d:
                    d[i].remove(d[i][j])
                    r[i] += 1
                else:
                    j += 1
            if not d[i]:
                p.append(i)
    
        for i in p:
            del d[i]
    
        def dfs(node, visited, graph):
            visited.add(node)
            for neighbor in graph.get(node, []):
                if neighbor not in visited:
                    dfs(neighbor, visited, graph)
            return visited
    
        for i in d:
            for j in d[i]:
                vi = set()
                vi = dfs(j, vi, d)
                t = 0
                for j in vi:
                    t += r[j]
                if not 1 & t:
                    kq += 1
    
        return kq
    
  • + 0 comments

    standard DFS

    int descendents(int current, const vector<vector<int>>& edges, int& components, vector<bool>& visited, vector<int>& size) {
        visited[current] = true;
        for (auto e : edges[current]) {
            if (!visited[e]) {
                size[current] = size[current] + descendents(e, edges, components, visited, size);;
            }
        }
        ++size[current];
        if (current != 1 and size[current] % 2 == 0) {
            ++components;
            return 0;
        }
        else return size[current];
    }
    
    int evenForest(int N, int E, const vector<vector<int>>& edges) {
        int components = 0;
        vector<bool> visited(N+1);
        vector<int> size(N+1);
        descendents(1, edges, components, visited, size);    
        return components;
    }
    
  • + 0 comments
    def treeLength(tree, node, count):
        if tree.get(node):
            for n in tree[node]:
                count = treeLength(tree, n, count + 1)
        return count
    
    def evenForest(t_nodes, t_edges, t_from, t_to):
        graph = {}
        for i in range(t_edges):
            if t_to[i] in graph:
                graph[t_to[i]].append(t_from[i])
            else:
                graph[t_to[i]] = [t_from[i]]
        count = 0
        for e in graph:
            for n in graph[e]:
                length = treeLength(graph, n, 1)
                if not length % 2:
                    count += 1
        return count
    
  • + 0 comments

    PYTHON SIMPLE DFS SOLUTION

    #!/bin/python3
    
    import math
    import os
    import random
    import re
    import sys
    
    
    from collections import defaultdict
    
    
    def _compute_edges_and_n_nodes(visit_node: int, children: dict, visited: set) -> (int, int):
        """
        Returns how many edges can remove this subtree and how many nodes it contains
        """
        # As children dict is bidirectional, we have to add nodes to visit in order to
        # avoid eternal loop
        visited.add(visit_node)
        
        # Exit case: Node is leaf, so it can not be a forest for its own
        if not len(children[visit_node]):
            return (0, 1)
            
        # We start counting nodes at 1 as we are assuming current node
        edges_to_remove, n_nodes = 0, 1
        for child in children[visit_node]:
            if child in visited:
                continue
            child_edges_to_remove, child_n_nodes = _compute_edges_and_n_nodes(child, children, visited)
            edges_to_remove += child_edges_to_remove
            n_nodes += child_n_nodes
            
        # If subtree is even, we add 1 edge to remove
        if not n_nodes % 2:
            edges_to_remove += 1
        return edges_to_remove, n_nodes
    
    
    # Complete the evenForest function below.
    def evenForest(t_nodes, t_edges, t_from, t_to):
        chldren = defaultdict(list)
        for n_from, n_to in zip(t_from, t_to):
            chldren[n_from].append(n_to)
            chldren[n_to].append(n_from)
        
        # We substract 1 to number of edges to remove because we don't want to count root
        return _compute_edges_and_n_nodes(1, chldren, set())[0] - 1
    
    
    if __name__ == '__main__':
        fptr = open(os.environ['OUTPUT_PATH'], 'w')
    
        t_nodes, t_edges = map(int, input().rstrip().split())
    
        t_from = [0] * t_edges
        t_to = [0] * t_edges
    
        for i in range(t_edges):
            t_from[i], t_to[i] = map(int, input().rstrip().split())
    
        res = evenForest(t_nodes, t_edges, t_from, t_to)
    
        fptr.write(str(res) + '\n')
    
        fptr.close()
    
  • + 0 comments

    Approach

    1. Use a Depth First Search (DFS) to calculate the size of each subtree.
    2. Count the number of subtrees with even numbers of nodes.
    3. The number of edges to remove is the number of even subtrees minus 1 (since we don't count the root's subtree).

    Solution

    Here is the PHP code:

    <?php
    
    function evenForest($t_nodes, $t_edges, $t_from, $t_to) {
        $graph = [];
        // Initialize graph
        for ($i = 1; $i <= $t_nodes; $i++) {
            $graph[$i] = [];
        }
    
        // Build adjacency list
        for ($i = 0; $i < count($t_from); $i++) {
            $graph[$t_from[$i]][] = $t_to[$i];
            $graph[$t_to[$i]][] = $t_from[$i];
        }
    
        // Array to store the size of each subtree
        $subtreeSize = array_fill(1, $t_nodes, 0);
    
        function dfs($node, $parent, &$graph, &$subtreeSize) {
            $subtreeSize[$node] = 1; // Include the node itself
            foreach ($graph[$node] as $neighbor) {
                if ($neighbor != $parent) {
                    $subtreeSize[$node] += dfs($neighbor, $node, $graph, $subtreeSize);
                }
            }
            return $subtreeSize[$node];
        }
    
        // Start DFS from node 1 (arbitrary choice for the root)
        dfs(1, -1, $graph, $subtreeSize);
    
        $removableEdges = 0;
    
        // Count removable edges
        for ($i = 2; $i <= $t_nodes; $i++) {
            if ($subtreeSize[$i] % 2 == 0) {
                $removableEdges++;
            }
        }
    
        return $removableEdges;
    }
    
    // Example usage:
    $t_nodes = 10;
    $t_edges = 9;
    $t_from = [2, 3, 4, 5, 6, 7, 8, 9, 10];
    $t_to = [1, 1, 2, 2, 3, 3, 4, 4, 5];
    
    echo evenForest($t_nodes, $t_edges, $t_from, $t_to); // Output should be 2
    
    ?>
    

    Explanation:

    1. Graph Construction: We use an adjacency list to represent the graph.
    2. DFS Traversal: We traverse the graph using DFS, calculating the size of each subtree.
    3. Subtree Size Calculation: The size of each subtree is stored in the $subtreeSize array.
    4. Count Removable Edges: We iterate through each node (except the root) and count subtrees of even size.

    This solution assumes that the tree is given in a 1-based index as in the example. If your tree nodes are 0-based, you should adjust the code accordingly.