Editorial for COI '19 #2 Pastiri
Submitting an official solution before solving the problem yourself is a bannable offence.
Denote the nodes of the tree by . We will identify a sheep/shepherd with the node it occupies.
Notice that the task can be seen as an instance of the so called set cover problem: For every node , consider the set of sheep which would be protected if we put a shepherd in node . Then we need to find the smallest subset of nodes such that equals the set of all sheep. The general set cover problem is NP-complete, but the specific tree structure here will help us to solve the problem in polynomial time.
Let's start with the first subtask, the case when the tree is a chain. A shepherd can protect only the first sheep to the left and/or to the right, so the family contains the following subsets:
- for every sheep ;
- for consecutive sheep such that is even.
We proceed with the following greedy algorithm: look at the first sheep. if the second one has the same parity, place a shepherd on the node halfway between them, otherwise place a shepherd in the same node as the first sheep. Next, remove the protected sheep and repeat the same algorithm. This solution has complexity .
To solve the second subtask, we make use of representing the subsets of sheep by bitmasks in . We first find the sets for every node in by running breadth-first search from every sheep.
We can then solve this set cover instance by dynamic programming. For each bitmask , let denote the minimum number of sets which cover . We iterate through the states in increasing order. When calculating , we iterate over all , and each time corresponds to some of the sets , we recalculate . To finish the transition, we put for all .
Memory complexity is , and time complexity is . (We leave the proof as an exercise.)
For the remaining subtasks, we first pick an arbitrary node as the root. For each sheep , we will refer to the set as its territory. We say that two sheep and are friends if their territories have a nonempty intersection. The main idea is to greedily place a shepherd that protects some sheep and all of the (currently) unprotected friends of that sheep. The following claim will help us with that:
Claim 1. For some sheep , let be its highest ancestor that is in its territory. Then, contains all friends of that are not deeper than . Proof. Let be a friend of that is not deeper than . If is in the subtree of , the claim is obvious, so assume the contrary. Take some node that is not part of territories of and , and let be the midpoint of the path between and . We have
where denotes the distance between nodes and . Also, for every sheep it's true that
which implies , and is proved analogously. Hence, is contained in the intersection of territories of and . Moreover, since is not deeper than , is an ancestor of , so it must be located on the path from to . Since is not contained in the subtree of , we have
so a shepherd in protects , as needed. □
According to Claim 1, the following algorithm is correct:
- Repeat until all sheep are protected:
- Place a shepherd in , where is (one of) the deepest currently unprotected sheep.
The straightforward implementation in the complexity , is sufficient to solve the third subtask. To solve the fourth subtask, we need to speed up the algorithm. For each node , let and denote the depth of the node and the distance to the closest sheep, respectively. We can calculate by running a BFS starting from each sheep. Alternatively, we can imagine that we added a dummy node connected to all the sheep and run the BFS starting in that node. The following fact will help us to efficiently determine for each sheep :
Observation 2. If is an ancestor of , then , where equality is attained if and only if is in the territory of .
Due to the above, is the index of first maximum of over all on the path from the root to . Thus we can calculate for each sheep by a simple depth-first search from the root.
The only thing left is maintaining the deepest unprotected sheep efficiently.
If we sort the sheep by decreasing depth, we can reduce this problem to maintaining the set of protected sheep.
Consider the directed graph with the same vertex set as the given tree, and with edges , where is an edge from the given tree such that .
Observation 3. For each node , is exactly the set of sheep such that there exists a path in from to .
Whenever we place a new shepherd, we can run a DFS from that node following edges of backwards, ignoring the nodes that were already visited. According to Observation 3, sheep is protected if and only if it was visited by the DFS. Since each node is visited at most once, the complexity of this part is linear.
Complexity of the solution is . Notice that the factor comes from sorting the sheep by depth, which is of course possible to do with complexity because the depths are at most . Therefore it's possible to solve the task in linear complexity.
Comments