Explanation

The theorem being used here is that if one vertex can both reach and be reached by all others, then every vertex in this graph can reach all others.

Let's say can[u][v]\texttt{can[u][v]} is true if you can go from vertex uu to vertex vv through a series of edges. Additionally, let's define the directed graph given in the statement as GG and the reverse of it (where an edge uvu \rightarrow v becomes vuv \rightarrow u) as GG'. Then, if can[1][x]\texttt{can[1][x]} for 1xn1 \leq x \leq n in both GG and GG', the answer is "YES".

To compute can[1][x]\texttt{can[1][x]}, we can run a dfs from from vertex 11 and check if you can reach vertex xx for all 1xn1 \leq x \leq n. If we can't, then print 11 xx if you're running the DFS on GG and xx 11 otherwise.

Proof

Let's do a proof by contradiction. Assume that can[1][x]\texttt{can[1][x]} is true for all vertices xx in both GG and GG', and there exists a pair of vertices u,vu, v such that can[u][v]=false\texttt{can[u][v]} = \texttt{false}. Since can[1][u]\texttt{can[1][u]} is true in GG', then can[u][1]\texttt{can[u][1]} must be true in GG. Additionally, can[1][v]\texttt{can[1][v]} must be true in GG. So, you can travel from u1vu \rightarrow 1 \rightarrow v, which contradicts the statement that can[u][v]=false\texttt{can[u][v]} = \texttt{false}. Thus, can[u][v]\texttt{can[u][v]} is true for all vertices u,vu, v.

Implementation

Time Complexity: O(N)\mathcal{O}(N)

from typing import List, Set
n, m = map(int, input().split())
forward_graph = [[] for _ in range(n)]
reverse_graph = [[] for _ in range(n)]
for _ in range(m):
a, b = map(int, input().split())
forward_graph[a - 1].append(b - 1)

The problem can also be solved using strongly connected components (SCC).

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!