CSES - Planets Cycles

Authors: Maggie Liu (C++), Qi Wang (Java), George Pong


Define the number of teleportations starting from a planet as the pathlength\texttt{pathlength} of that planet. For each planet that hasn't been visited, we want to find its pathlength\texttt{pathlength}. Call the planet we are performing dfs\texttt{dfs} from the start\textit{start}. As we perform dfs\texttt{dfs} from the start\textit{start}, keep track of the planets seen, in order, in the path\texttt{path} queue and keep track of steps\texttt{steps}, the length of the path (which is also the pathlength\texttt{pathlength} of the start\textit{start}). When we reach a planet that has already been visited (call this planet the repeat\textit{repeat}), add the pathlength\texttt{pathlength} of the repeat\textit{repeat} to the current step\texttt{step} count because we would continue to visit all of the planets that repeat\textit{repeat} would go on to visit.

Once we have path\texttt{path} and steps\texttt{steps} we can calculate the pathlength\texttt{pathlength} of all the planets in this path\texttt{path}. We know the repeat\textit{repeat} will always be the planet at the end of the path\texttt{path}, but it may appear elsewhere as well. We can break this down into two cases:

  1. The repeat\textit{repeat} was visited twice in the current path\texttt{path}. The planets in the path\texttt{path} between the two occurrences of the repeat\textit{repeat} form a cycle\textit{cycle}.
  2. The repeat\textit{repeat} only appears at the end of the current path\texttt{path}. All of the planets in the path\texttt{path} are not part of a cycle\textit{cycle}.

For planets inside a cycle\textit{cycle}, the repeating planet when starting from that planet is itself. For all the planets in the path\texttt{path} but outside the cycle\textit{cycle}, the planet that repeats when starting from each planet will still be the repeat\textit{repeat}.

Since the planets outside the cycle\textit{cycle} all have paths ending at the repeat\textit{repeat}, each one's pathlength\texttt{pathlength} is 11 less than the previous'. So, as we iterate through the planets along the path\texttt{path} that are outside the cycle\textit{cycle}, the pathlength\texttt{pathlength} will decrease by 11 each time, starting from the start\textit{start} with a pathlength\texttt{pathlength} of steps\texttt{steps}. Once we get to the cycle\textit{cycle}, the pathlength\texttt{pathlength} of the planets will all be equal to the pathlength\texttt{pathlength} of the repeat\textit{repeat}, which is the length of the cycle\textit{cycle}.

C++

Implementation

#include <iostream>
#include <queue>
using namespace std;
void dfs(int planet);
bool visited[200000]{};
int destinations[200000];
int pathlength[200000]{};
queue<int> path;
int steps = 0;

Java

Implementation

import java.io.*;
import java.util.*;
public class PlanetCycles {
static int N, steps;
static int[] destinations, pathlength;
static boolean[] visited;
static LinkedList<Integer> path = new LinkedList<>();
public static void main(String[] args) {
Kattio io = new Kattio();

Python

n = int(input())
planets = list(map(lambda i: int(i) - 1, input().split()))
path_length = [0] * n
visited = [False] * n
for i in range(len(planets)):
"""
We dfs from the current planet until we end up at a planet we have already
visited. Note that the visited planet is not added to the path array.

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!