C++ · Solution

Bobs Portal Travel

This C++ solution uses graph traversal for Bobs Portal Travel. Read the reasoning, inspect the code, or try your own test case below.

Graphs & treesGraph traversalC++72 lines
Solution034of 248
Download C++ file ↓ Search the library → Open full Code Lab ↗ Report an issue ↗

Approach

Graph traversal

Bobs Portal Travel: explore states in breadth-first order with a queue, marking each state when it is reached so every vertex and edge is processed only as needed.

Breadth-first searchGraphs

Problem and code

Useful links.

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

View exact source file ↗
Implementation

bobs_portal_travel.cpp

C++

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    vector<int> cycle;
    bool dfs(int cur, vector<vector<int>> &adj, vector<int> &color, vector<int> &parent, vector<int> &depth){ 
        //0 = not visited, 1 = visiting, 2 = visited
        color[cur] = 1;
        for(int nxt : adj[cur]){
            if(color[nxt] == 0){
                parent[nxt] = cur;
                depth[nxt] = depth[cur] + 1;
                if(dfs(nxt, adj, color, parent, depth)) return true; // found cycle already
            } else if(color[nxt] == 1){;
                int x = cur;
                cycle.push_back(nxt);
                while(x != nxt){
                    cycle.push_back(x);
                    x = parent[x];
                }
                reverse(cycle.begin(), cycle.end());
                return true;
            }
        }
        color[cur] = 2;
        return false;
    }
    signed main(){
        ios::sync_with_stdio(0); cin.tie(0);
        int n, k; cin >> n >> k;
        vector<vector<int>> adj(n + 1);
        for(int i = 1; i <= n; i++){
            int c; cin >> c;
            adj[i].push_back(c);
        }
        vector<int> color(n + 1, 0), parent(n + 1, -1), depth(n + 1, 0);
        // solve with colouring dfs
        dfs(1, adj, color, parent, depth); 
        int step = 0, entry = -1; // step from one to first cycle node from that path
        queue<int> q;
        q.push(1);
        vector<int> dist(n + 1, INT_MAX);
        vector<bool> in_cycle(n + 1, 0);
        for(int v : cycle) in_cycle[v] = 1;
        dist[1] = 0;
        while(!q.empty()){
            int cur = q.front(); q.pop();
            if(in_cycle[cur]){
                step = dist[cur];
                entry = cur;
                break;
            }
            for(int nxt : adj[cur]){
                if(dist[cur] + 1 < dist[nxt]){
                    dist[nxt] = dist[cur] + 1;
                    q.push(nxt);
                }
            }
        }
        if(k < step){
            int cur = 1;
            while(k--){
                cur = adj[cur][0];
            }
            cout << cur << '\n';
            return 0;
        }
        int remain = (k - step) % cycle.size();
        int pos = find(cycle.begin(), cycle.end(), entry) - cycle.begin();
        int ans = cycle[(pos + remain) % cycle.size()];
        cout << ans << '\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.