cppAcademy
FROM LEARNING TO COMPETING

Expert.
Put your skills to the test.

Bulgarian Informatics Group A · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group A also includes challenging national-level problems. The 109 National-round tasks shared by Groups A and B retain their existing permanent URLs and explanations. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP A2024 · HardLayered breadth-first search

Travel with a Flight Budget

National Olympiad — Regional round (2024 season)

Submission name: travel.cpp

Problem summary

An undirected network has bus and airplane edges. Find the fewest vehicles needed from city 1 to city N while using at most K airplanes.

Input

N M K; then M triples a b t, with t=1 for a bus and t=2 for an airplane.

Output

Minimum edge count, or −1 if no permitted route exists.

Constraints

2 ≤ N ≤ 200000; 1 ≤ M ≤ 3N; 1 ≤ K ≤ 2.

Worked example

Official statement example.

Input

5 5 1
1 2 1
2 3 1
3 5 2
2 4 1
4 5 2

Output

3

Solution analysis

  1. A city alone is insufficient to describe a search state: arriving with no flights used can enable a continuation unavailable after spending the budget. Use states (city, flights used), with K+1 layers.
  2. A bus keeps the layer, and an airplane increases it by one if the budget allows. Every transition uses exactly one vehicle, so ordinary BFS from (1,0) finds shortest distances in this expanded graph.
  3. In the example BFS can follow 1→2→3→5, reaching (5,1) in three transitions. The result is the minimum distance to city N in any permitted layer; unreachable layers are ignored.

Why it works

Each permitted route corresponds to an expanded-graph walk with the same number of edges, and every expanded walk represents a permitted route. BFS finds shortest walks in an unweighted graph, and minimizing over final layers therefore gives exactly the required answer.

Complexity: O((N+M)(K+1)) time and O(N(K+1)+M) space.

Watch out. Do not mark a city visited globally; different flight counts are different states.

Commented C++17 solution

An independently written complete program with standard headers.

// Key idea: Each permitted route corresponds to an expanded-graph walk with the same number of edges,
// and every expanded walk represents a permitted route. BFS finds shortest walks in an unweighted
// graph, and minimizing over final layers therefore gives exactly the required answer.
#include<iostream>
#include<queue>
#include<utility>
#include<vector>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m,k;
    cin>>n>>m>>k;
    vector<vector<pair<int,int>>>graph(n);
    for(int i=0;i<m;++i){
        int a,b,type;
        cin>>a>>b>>type;
        --a;
        --b;
        graph[a].push_back({b,type-1});
        graph[b].push_back({a,type-1});
    }
    vector<vector<int>>distance(n,vector<int>(k+1,-1));
    queue<pair<int,int>>pending;
    distance[0][0]=0;
    pending.push({0,0});
    while(!pending.empty()){
        auto[u,used]=pending.front();
        pending.pop();
        for(auto[v,flight]:graph[u]){
            int next=used+flight;
            if(next<=k&&distance[v][next]==-1){
                distance[v][next]=distance[u][used]+1;
                pending.push({v,next});
            }
        }
    }
    int answer=-1;
    for(int value:distance[n-1]){
        if(value!=-1&&(answer==-1||value<answer)){
            answer=value;
        }
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗