2127. Maximum Employees to Be Invited to a Meeting

Question

CleanShot 2025-01-26 at 21.52.45.png

Code

class Solution:
    def maximumInvitations(self, favorite: List[int]) -> int:

        '''
        Two cases:

        1. Closed cycle, last node connect to the first node
        2. Cycle with two node and two edges, with other node pointing towards them 

        '''

        N = len(favorite)
        visit = [False] * N 
        longest_cycle = 0 

        length_2_cycles = []

        for i in range(N):
            if visit[i]:
                continue

            start, cur = i, i
            cur_set = set()

            while not visit[cur]:
                visit[cur] = True
                cur_set.add(cur)
                cur = favorite[cur]

            if cur in cur_set:
                length = len(cur_set)
                while start != cur:
                    length -= 1
                    start = favorite[start]

                if length == 2:
                    length_2_cycles.append([cur, favorite[cur]])
                longest_cycle = max(longest_cycle, length)

        inverted = defaultdict(list)

        for dst, src in enumerate(favorite):
            inverted[src].append(dst)

        # Prove that all two edge cycle subset are disjoint. 
        def bfs(src, parent):
            q = deque([(src, 0)])
            max_length = 0

            while q:
                cur, cur_len = q.popleft()
                if cur == parent:
                    continue

                max_length = max(max_length, cur_len)

                for nei in inverted[cur]:
                    q.append([nei, cur_len + 1])
            return max_length

        total_length = 0
        for n1, n2 in length_2_cycles:
            total_length += bfs(n1, n2) + bfs(n2, n1) + 2

        return max(longest_cycle, total_length)