今日题目
https://leetcode.com/problems/maximum-employees-to-be-invited-to-a-meeting/description/
解题思路
本题给出一个有向图,其中包含环。为了找出环,可以使用拓扑排序:找出入度为 0 的节点,并将其及其对应的边删除。
这样处理后,图中剩余的节点都处于环内。
本题中,有两种方式让所有人入座:
- 一个完整的环,环中每个人的左手边坐着自己最喜欢的人。
- 当两个人互相是对方最喜欢的人时,他们两人本身就构成一个完整的环,而喜欢他们的人可以形成一条链指向他们。这种结构比较特殊,因为每个人都能找到自己最喜欢的人,而无需构成完整的环。因此,会议室中可以同时存在多个这样的结构。
算法步骤
- 使用拓扑排序找出图中所有的环。
- 找出所有两人互为最喜欢的特殊情况。
- 返回单个最大环的大小,或返回多个特殊结构的总大小,取两者的最大值。
复杂度分析
-
时间复杂度:$O(N)$
-
空间复杂度:$O(N)$
代码
class Solution:
def maximumInvitations(self, favorite: List[int]) -> int:
N = len(favorite)
du = [0] * N
l = [1] * N
for x in favorite:
du[x] += 1
q = deque([])
for i in range(N):
if du[i] == 0:
q.append((i, 1))
while(len(q) > 0):
x, leng = q.popleft()
to = favorite[x]
du[to] -= 1
l[to] = max(l[to], leng + 1)
if du[to] == 0:
q.append((to, leng + 1))
vis = [0] * N
def dfs(i):
to = favorite[i]
vis[i] = 2
if vis[to] == 2:
return 1
return dfs(to) + 1
ans = 0
res = 0
for i in range(N):
if du[i] != 0 and vis[i] == 0:
tmp = dfs(i)
# print(i, tmp)
if tmp == 2:
# print(i, favorite[i], l[i], l[favorite[i]])
res += l[i] + l[favorite[i]]
else:
ans = max(ans, tmp)
return max(ans, res)