看见题目知道时间复杂度不超过(mlogm)。
这题用强连通分量 Tarjan 算法,强联通:对于任意两个点u和v,u可以到达v,v也可以到达u。这题需要考虑有重边,自环,同样别忘记可能会有两个点u和v,u不能到达v,v也不能到达u的情况,就是u和v不在同一个图中,数据中会存在几个图的情况。
Tarjan 算法主要是维护两个列表dnf和low,dnf[i]记录到达i这个点的次序,low记录i这个点的祖先次序。如果dnf[i]==low[i],就是说i这个点就是祖先节点,如果dnf[i] != low[i],那么i这个点是某个祖先节点的儿子。
洛谷超时一个,还有待改进。
遇到一个问题就是,需要考虑数据中存在不同的图!!!!
from collections import defaultdict, dequedef taij(node):global idxdfn[node] = idxlow[node] = idxidx += 1stack.append(node)v[node] = 1vis[node] = 1for nex in edge[node]:if vis[nex] == 0:taij(nex)low[node] = min(low[node], low[nex])elif v[nex]:low[node] = min(low[node], dfn[nex])if dfn[node] == low[node]:ls = []while dfn[stack[-1]] != dfn[node]:nex = stack.pop()ls.append(nex+1)v[nex] = 0nex = stack.pop()v[nex] = 0ls.append(nex+1)ls = sorted(ls[::-1])ans.append(ls)n, m = map(int, input().split())
edge = defaultdict(list)
dfn = [0]*n
low = [0]*n
stack = deque()
v = [0]*n
vis = [0]*n
idx = 0
ans = []
for _ in range(m):uu, vv = map(int, input().split())edge[uu-1].append(vv-1)
taij(0)
for i in range(n):if vis[i] == 0:taij(i)leth = len(ans)
print(leth)
ans.sort()
for i in range(leth):for j in ans[i]:print(j, end=' ')print()