cppAcademy
FROM LEARNING TO COMPETING

Proficient.
Put your skills to the test.

Bulgarian Informatics Group B · 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 B also includes challenging national-level problems. National-round tasks shared by Groups A and B are included. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP B2016 · Medium0-1 BFS

Fewest Wrong-Way Streets

National Olympiad — Regional round (2016 season)

Submission name: town.cpp

Problem summary

Travel from intersection a to b, minimizing streets traversed against their directed orientation. Each reversed street costs one violation.

Input

n a b, then directed edges p q until end of input.

Output

Minimum violations, or X when no undirected route exists.

Constraints

n ≤ 200000; at most 400000 streets; at most one street in either direction between a pair.

Worked example

An independently prepared example for this explanation.

Input

4 1 4
4 3
3 2
1 2
4 2

Output

1

Solution analysis

  1. Replace each directed street p→q by a zero-cost arc p→q and a unit-cost arc q→p. Every allowed journey then has total cost equal to its number of violations.
  2. Use 0-1 BFS: relax a zero-cost improvement at the front of a deque and a unit-cost improvement at the back. This maintains the same distance ordering as Dijkstra’s algorithm for weights zero and one.
  3. In the example, 1→2 is free and traversing 2→4 reverses the street 4→2 once. Hence a route with one violation exists. No all-forward route reaches 4, so the minimum is one.

Why it works

The arc construction gives a cost-preserving correspondence between journeys and graph paths. 0-1 BFS processes distance layers in nondecreasing order because new distances differ from the current one by only zero or one. Its shortest path distance therefore minimizes violations; an infinite distance means no route.

Complexity: O(n+m) time and O(n+m) space.

Watch out. Read streets until EOF; no edge count is provided. A reversed edge costs one, irrespective of its length.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<vector>
#include<deque>
#include<utility>
// Algorithm: Replace each directed street p→q by a zero-cost arc p→q and a unit-cost arc q→p.
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,start,target;
    cin>>n>>start>>target;
    vector<vector<pair<int,int>>>graph(n+1);
    int from,to;
    while(cin>>from>>to){
        graph[from].push_back({to,0});
        graph[to].push_back({from,1});
    }
    const int infinity=1000000000;
    vector<int>distance(n+1,infinity);
    vector<bool>finished(n+1,false);
    deque<int>pending;
    distance[start]=0;
    pending.push_front(start);
    while(!pending.empty()){
        int vertex=pending.front();
        pending.pop_front();
        if(finished[vertex]){
            continue;
        }
        finished[vertex]=true;
        for(auto edge:graph[vertex]){
            int next=edge.first,weight=edge.second;
            if(distance[next]>distance[vertex]+weight){
                distance[next]=distance[vertex]+weight;
                if(weight==0){
                    pending.push_front(next);
                }
                else{
                    pending.push_back(next);
                }
            }
        }
    }
    if(distance[target]==infinity){
        cout<<"X\n";
    }
    else{
        cout<<distance[target]<<'\n';
    }
}

Source: Arena Olimpiici ↗