Editorial for Baltic OI '18 P1 - Love Polygon
Submitting an official solution before solving the problem yourself is a bannable offence.
In essence, we have a directed graph where each vertex has exactly one outgoing arc. We are asked to redirect some of the arcs so that each vertex is in a "pair" and we are asked to do it with the minimum number of redirects. This type of graph, called a "functional graph", inevitably takes the form where each connected component is a directed cycle with directed trees branching off of it.
Note that some sort of solution is always possible if -1
. The following explanations deal with the case where
Subtask 1
Let
- If we remove the edges originating from people in
, all connected components in the resulting graph must have at most vertices. This is because the final graph can be constructed by only adding edges to this graph, and in the final graph all connected components have vertices. - No person who loves themselves can be in
, because then they will love themselves in the final arrangement, which is not permitted.
If these conditions hold,
To solve the problem, we can iterate over all sets
An alternative approach is to use dynamic programming on subsets in
Subtask 2
In order for everyone to be loved by someone, everyone must be loved by exactly one person. In this subtask, each connected component of the graph takes the form of a cycle. Let's process each component separately, let
Subtask 3
Since there are no "love polygons", that must mean the cycle in each connected component of the graph consists of one character loving themselves. This means each connected component takes the form of a directed tree with all edges directed towards the root.
We call a set of vertices
- For each vertex in
, its parent is not in ; - For each vertex in
, none of its children are in ; - For each vertex in
, none of its siblings are in .
Let
- The parent of
must be shot with an arrow to love . Therefore the parent of is not in . - All children of
must be shot with an arrow, otherwise they would end up in a pair with , but we know will be paired off with its parent. Therefore no children of are in . - All siblings of
must be shot with an arrow, otherwise they would end up in a pair with the parent of , but we know the parent of will be paired off with . Therefore no siblings of are in .
Hence,
Our task is therefore to calculate the size of the largest lucky set that doesn't contain any roots. This can be done using dynamic programming.
Let
to be the size of the maximum lucky set within the subtree of whose member itself is not. to be the size of the maximum lucky set within the subtree of whose member itself is.
The size of the largest lucky set is then
clearly holds. Lucky sets within the subtree of
- Not contain any of the children of
. The largest of them has size . - Contain exactly one of the children of
. The largest lucky set containing , a child of , has size .
All those kinds of lucky sets exist, the largest of them has therefore size:
Therefore,
To sum it up, for any vertex
and
hold. Using those recurrences, we can iterate over all connected components of the graph, do a depth-first search on them and calculate the values of
Subtask 4
The subtask is solved similarly to subtask 3. We will process each connected component separately. If the cycle of the current component consists of just one character, we will process it the same way as in subtask 3. If the cycle is longer, we pick one arbitrary character. In the optimal solution, that character either is in a relationship with the person they love, or isn't. In both cases, we can eliminate some arcs from the component so that the component becomes a forest of directed trees. Using the solution from subtask 4, we can calculate the number of love arrows needed in both situations and pick the better one. This solves the subtask in
Comments