CSES - Planets Queries II
Authors: Michael Cao, Benjamin Qi, Kevin Sheng
In this problem, we are given a functional graph and asked queries for the minimum distance between two vertices and .
Structure of the Graph
Notice that all functional graphs can be broken down into a bunch of "components". Each of these components consists of many trees directed towards the root, and a single cycle composed of said roots and some other nodes.
Here's an example of a possible "component". The trees are circled in red:
Given this, we can essentially break down each query into three cases:
Both in Tree
If both and are in a tree, we first have to get the distance from each node to the cycle. This can be precalculated for all nodes with BFS.
First of all, if 's distance is greater than that of 's, we can't get to because using a teleporter can only decrease our distance to the cycle.
But if this condition isn't satsified, we start at and use the teleporters until our distance to the cycle is equal to that of 's. If we've actually ended up at , then our answer is the difference between the distances. Otherwise, it's impossible to reach .
To see which planet we end up at if we teleport times, we can use binary jumping.
Both in Cycle
If both are in a cycle, we get both and 's index in the cycle. Let's call these indices and respectively. Now, if , then our answer is . On the other hand, if , then our answer is .
One in Each
This case is really two cases, but we only really need to consider one of them.
If is in a cycle but is in a tree, it's impossible to reach from because we can only go from a tree to a cycle, not vice versa.
On the other hand, if is the one in the tree, we get which node in the cycle 's tree connects to, which is also the root. Then this reduces to a version of the second case: we just have to add the distance from to the root as well.
Warning!
Note that all three of these cases assume and are in the same component. If they're in different components, we can't reach from .
Implementation
Time Complexity:
C++
#include <cmath>#include <iostream>#include <map>#include <vector>using std::cout;using std::endl;using std::vector;int main() {
Java
import java.io.*;import java.util.StringTokenizer;public class PlanetQueries2 {private static int MAX_HEIGHT = 20;private static int[][] binaryLifting;private static int[] arr;private static int[] len;private static boolean[] visited;
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!