DOJ logoDOJ
Problems
Recently added problemsSaved problems
CategoriesDLCContestsGroupsTeamsBoard
Ranking
Solved Problem RankingStreak rankingDOJ Power ranking
Status
Call for TasksLoginRegister
DOJ logoDOJ

Community online judge with OI-style subtask scoring, Elo ratings, and Discord-backed certification.

Problems
ProblemsCategories
Community
ContestsRankingBoardNoticesHost an external contestGuide
Account
LoginRegisterJudge Status
Policy
Terms of ServiceDLC RulesPrivacyAPI documentationLanguage runtimesContest rank rewardsRating and performance
© 2026 DOJ
All rights reserved
Editorial

Finding dfs tree

Back to problem

Editorial

Initially, regard every vertex as a separate component. Vertices joined by already selected tree edges are contracted into one component.

An incoming edge of a current component BBB is an original directed edge whose tail is outside BBB and whose head is inside BBB. Count edges themselves, not the number of distinct source components.

Find a component BBB with exactly one incoming edge. Let that edge be u→vu \to vu→v, and let AAA be the component containing uuu. Select u→vu \to vu→v as a tree edge, set Pv=uP_v=uPv​=u, and merge AAA and BBB. The root vertex of the merged component is the former root vertex of AAA.

Repeat until no such contraction is possible.

Correctness

Suppose BBB has the unique incoming edge u→vu \to vu→v and is attached below AAA. This is the only edge directed from the AAA side to the BBB side. Therefore, every other edge that becomes internal when the two components are merged is directed from BB to . Such an edge points from the descendant component to the ancestor component in the newly constructed tree. Conditions inside the old components remain valid by induction.

Conversely, suppose a valid tree exists and more than one component remains. Contract every current component in that valid tree. The component tree has a leaf component. Exactly one tree edge enters this leaf from its parent component. No non-tree back edge can additionally enter it, because there is no descendant component outside the leaf component. Hence some component has exactly one incoming edge.

Eligible contractions can be exchanged. A contraction does not change the incoming-edge set of any unrelated component; it only replaces its two involved components by their union. Therefore, if a complete contraction sequence exists, any currently eligible contraction may be performed first.

If one component remains, the selected N−1N-1N−1 edges form a valid tree. If several components remain and none has exactly one incoming edge, no valid tree exists.

Efficient implementation

For every component, store:

  • the list of its vertices,
  • a hash set of edge indices entering the component from outside,
  • the component root whose parent has not been assigned.

When merging two components, move the component with fewer vertices into the larger one.

Inspect all outgoing edges of vertices in the smaller component to erase edges that become internal from the larger component's incoming-edge set. Move the smaller incoming-edge set into the larger set, discarding edges whose tails are already in the larger component.

Whenever a vertex moves, the size of its component at least doubles. Thus every vertex and edge is processed only O(log⁡N)O(\log N)O(logN) times. With hash sets, the expected time complexity is O((N+M)log⁡N)O((N+M)\log N)O((N+M)logN) and the memory complexity is O(N+M)O(N+M).

B
AAA
O
(
N
+
M)