CSES · 1751

Planets Cycles

This C++ solution uses simulation for CSES 1751 Planets Cycles. Read the reasoning, inspect the code, or try your own test case below.

1751Graphs & treesSimulationC++48 lines
Solution165of 248
Open official problem ↗ Download C++ file ↓ Search the library → Open full Code Lab ↗ Report an issue ↗

Approach

Simulation

Planets Cycles matches the functional-graph input and the code's cycle-distance count for every planet.

Graphs & trees

Problem and code

Useful links.

Written by benbenyaojifen. Try the problem first, then compare your approach with the code.

Open official problem ↗View exact source file ↗
Implementation

planets_cycles.cpp

C++

    #include <bits/stdc++.h>
    using namespace std;
     
    void floyd_cycle(int x, const vector<int> &succ, vector<int> &ans){
        int a = succ[x], b = succ[succ[x]];
        // meet inside the cycle, but bail if we hit a known node
        while (a != b) {
            if (ans[a] || ans[b]) break;              // <<< early exit if chain already solved
            a = succ[a]; b = succ[succ[b]];
        }
        // Only do cycle work if we actually found a *new* cycle
        if (a == b && ans[a] == 0) {                  // <<< skip if cycle already labeled
            // find cycle entry
            a = x;
            while (a != b) { a = succ[a]; b = succ[b]; }
            int entry = a;
     
            // find cycle length
            int len = 1, nxt = succ[entry];
            while (nxt != entry) { nxt = succ[nxt]; len++; }
     
            // fill cycle nodes
            int v = entry;
            do { ans[v] = len; v = succ[v]; } while (v != entry);
        }
        // fill tail toward the first known node/cycle
        vector<int> path;
        int v = x;
        while (ans[v] == 0) { path.push_back(v); v = succ[v]; }
        for (int i = (int)path.size() - 1; i >= 0; --i)
            ans[path[i]] = ans[succ[path[i]]] + 1;
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        int n; cin >> n;
        vector<int> succ(n + 1), ans(n + 1);
        for(int i = 1; i <= n; i++){
            cin >> succ[i];
        }
        for(int i = 1; i <= n; i++){
            if(ans[i] == 0) floyd_cycle(i, succ, ans);
        }
        for(int i = 1; i <= n; i++){
            cout << ans[i] << (i == n ? "\n" : " ");
        }
        return 0;
    }
        

Did this explanation save you time? I'm a Grade 11 student building this free library to make difficult algorithms easier to understand.

Buy me a coffee ↗Keep studying →

Test this problem

Run your code here.

Paste your code, run a test case, compare the output, or trace selected values.

Full trace, comparison & stress testing ↗
StatusReady
Output
No run yet.
Diagnostics
No diagnostics yet.

Each run is isolated and has strict limits. Passing one test does not guarantee the judge will accept the solution.