Editorial for COCI '23 Contest 1 #5 Mostovi
Submitting an official solution before solving the problem yourself is a bannable offence.
Prepared by: Patrick Pavić
For solving the first and second subtasks, it was sufficient to attempt a depth-first search on the graph after removing each edge and check if the graph is connected.
To solve the remaining subtasks, similar to the classical algorithm for finding bridges, our algorithm will work with the DFS tree of the given graph. A specific property of the DFS tree is that all edges not in the tree connect a node to one of its descendants. We will refer to nodes of that kind as back edges. The edges that have the property sought in the task will be called good edges.
First, we will check for all edges in the DFS tree to see if they are good edges. This algorithm will not differ much from the algorithm for finding articulation points, and we leave the details to the reader as an exercise. This was sufficient to solve the fourth subtask, while checking the remaining edges using the same algorithm as in the first two subtasks.
Now, let's consider a back edge and the components formed by its removal. It is necessary to check if these components are connected to each other by back edges. If they are not, that edge is good. These components can be divided into four primary groups:
- - a component that contains the root of the DFS tree (the node from which we initiated the DFS)
- - the components formed by removing node in its subtree, except the one that contains node
- - a component containing the path between nodes and (as the edge is not in the tree, this path will always exist)
- - the components formed by removing node in its subtree
Assuming that the graph remains connected, all components of the group must contain a back edge within them that connects them to the component. Similarly, all components of the form must have a back edge connecting them either to the component or to the component (note that they cannot be connected to the component due to the condition of the DFS tree). Finally, to keep the graph connected, at least one of the following two statements must be true:
- There exists a component that contains both a back edge to the component and to the component.
- There exists a back edge from the component to the component.
All of these conditions can be efficiently checked using various segment trees ordered by the preorder traversal of the DFS tree. One very useful thing is to compute, for each subtree, the highest and lowest back edge leaving that subtree (disregarding back edges completely in the subtree). This was possible to calculate using segment trees or the small to large algorithm. Depending on the implementation, it was achievable to reach a complexity of or , which was sufficient to solve the problem. Slower implementations solved the third subtask.
Comments