leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

count_structures_max_dist_cities.py (2638B)


# 1617. Count Subtrees With Max Distance Between Cities
import collections

"""
there are 'n' cities numbered from 1 to 'n'. you are given an array 'edges'
of size 'n - 1', where 'edges[i] = [ui, vi]' represents a bidirectional edge
between cities 'ui' and 'vi'. there exists a unique path between each pair of
cities. in other words, the cities form a tree. a subtree is a subset of
cities where every city is reachable from every other city in the subset,
where the path between each pair passes through only the cities from the
subset. two subtrees are different if there is a city in one subtree that is
not present in the other. for each 'd' from 'n - 1', find the number of
subtrees in which the maximum distance between any two cities in the subtree
is equal to 'd'. return an array of size 'n - 1' where the d'th element is
the number of subtrees in which the maximum distance between any two cities
is equal to 'd'. notice that the distance between the two cities is the
number of edges in the path between them.
"""


class Solution(object):
    def countSubgraphsForEachDiameter(self, n, edges):
        """
        :type n: int
        :type edges: List[List[int]]
        :rtype: List[int]
        """

        def bfs(src, cities):
            visited, max_dist = {src}, 0
            q = collections.deque([(src, 0)])
            while len(q) > 0:
                u, d = q.popleft()
                max_dist = d
                for v in graph[u]:
                    if v not in visited and v in cities:
                        visited.add(v)
                        q.append((v, d + 1))
            return max_dist, visited

        def farthest(state):
            cities = set()
            for i in range(n):
                if (state >> i) & 1 == 1:
                    cities.add(i)
            ans = 0
            for i in cities:
                max_dist, visited = bfs(i, cities)
                if len(visited) < len(cities):
                    return 0
                ans = max(ans, max_dist)
            return ans

        graph = collections.defaultdict(list)
        for u, v in edges:
            graph[u - 1].append(v - 1)
            graph[v - 1].append(u - 1)
        ans = [0] * (n - 1)
        for state in range(1, 2**n):
            d = farthest(state)
            if d > 0:
                ans[d - 1] += 1
        return ans


if __name__ == "__main__":
    obj = Solution()
    print(obj.countSubgraphsForEachDiameter(n=4, edges=[[1, 2], [2, 3], [2, 4]]))
    print(obj.countSubgraphsForEachDiameter(n=2, edges=[[1, 2]]))
    print(obj.countSubgraphsForEachDiameter(n=3, edges=[[1, 2], [2, 3]]))