Pattern visualizer
Find Eventual Safe States
Checking every path from a node would be exponential, but the question is really the opposite of Course Schedule's: instead of counting arrows IN and peeling from the sources, count arrows OUT and peel from the dead ends. A node with 0 outgoing edges is safe for free. Once every node IT points to is confirmed safe, it becomes safe too — so 'confirmed safe' spreads backward along the arrows exactly like 'no prerequisites left' spread forward. Whatever never gets reached is stuck feeding a cycle. Animated on: 6 nodes with moves 0->1, 0->2, 1->2, 1->3, 2->5, 3->0, 4->5 (a->b means a can move to b) — which nodes are eventually safe (every path from them dead-ends)?.
Peel dead ends backward: a node is safe once every node it points to is already safe
Nodes and their moves
6 nodes, and an arrow a to b means a can move to b. A node is safe only if EVERY path out of it eventually dead-ends at a node with no outgoing edges — one arrow into a cycle is enough to disqualify it, so the question is which nodes can reach one.
1FUNCTION eventualSafeNodes(n, edges):2 FOR EACH (a, b) IN edges3 APPEND b TO adj[a]4 APPEND a TO radj[b]5 outdeg[a] <- outdeg[a] + 16 queue <- EVERY u WHERE outdeg[u] = 07 WHILE queue NOT EMPTY8 u <- REMOVE FIRST FROM queue9 safe[u] <- TRUE10 FOR EACH p IN radj[u]11 outdeg[p] <- outdeg[p] - 112 IF outdeg[p] = 013 APPEND p TO queue14 RETURN SORT(EVERY u WHERE safe[u])
← / → step · space play · Home restart