Editorial for JOI '19 Open P3 - Virus Experiment
Submitting an official solution before solving the problem yourself is a bannable offence.
Solution
Preprocessing the direction of the wind, for each inhabitant, if we know the status (infected or uninfected) of
adjacent inhabitants, we can determine whether he or she gets infected or not in
time.
We consider a directed graph whose vertices are inhabitants and edges are the relations "if only this inhabitant
is infected, that inhabitant is finally infected." We decompose it into strong connected components. We need
to calculate the minimum number of vertices in a strong connected component of outdegree . We also need to
calculate the number of strong connected components attaining the minimum number of vertices.
This can be done by the following DFS (depth-first search).
- We construct a union-find, where we can list all vertices in a union by a merging technique.
- For a vertex, if every vertex in a union where this vertex belong to is infected, we search the next vertex to be infected.
- If we arrive at a vertex where we already visited, we stop searching if it is not an ancestor of DFS. If it is an
ancestor of DFS, we merge the union of all vertices in the path we followed. (We can determine whether it
is an ancestor or not in
time.)
Then, a union means "the set of vertices which infect each other."
There is a difficulty in speeding up the step 2, especially in listing the vertices adjacent to a union. There are two cases:
- (A) The union consists of one vertex (i.e., we arrive at a vertex for the first time).
- (B) We are considering union which was created by merging two already-existing unions.
The case (A) can be done in time.
Concerning the case (B), if a vertex is adjacent to only one of two unions to be merged, it was already searched
by DFS before merging the unions. Therefore, we need only consider a vertex which is adjacent to both of the two
unions. We calculate all vertices which are adjacent to the smaller union. By merging technique, the amortized
time complexity is .
Solution (randomized algorithm)
Take a sequence of vertices where every vertex appears exactly once.
For each of the vertices , we do a naive simulation under the condition that it is the only initial infected
vertex. In a simulation where
is the initial infected vertex, if the vertex
is infected and
, then we quit
the simulation.
For simulations which are not quit on the way, we need to calculate the minimum number of vertices which are finally infected, and the number of simulations which attain the minimum.
In this solution, the worst time complexity is . If we take the initial sequence
randomly, the time
complexity becomes roughly
.
Comments