Clasa a XI-a · Grafuri neorientateRead in English

Lanțul de lungime minimă între două noduri (BFS) în C++

În engleză: Shortest path between two nodes (BFS)

O(n²)C++1793 de linii2 exemple

Ideea

Lungimea unui lanț este numărul de muchii. Parcurgerea în lățime pornită din x descoperă nodurile în ordinea distanței față de x, deci prima dată când ajunge într-un nod o face pe un lanț de lungime minimă. Reținem dist[y] (distanța) și tata[y] (nodul din care a fost descoperit y). Lanțul se reface mergând din y prin tați până la x, apoi se afișează invers. Datele: n m, cele m muchii, apoi nodurile x și y.

Descrierea în engleză

The length of a path is its number of edges. Breadth-first search started from x discovers the nodes in order of their distance from x, so the first time it reaches a node it does so along a shortest path. We keep dist[y] (the distance) and tata[y] (the node from which y was discovered). The path is rebuilt going from y through the parents up to x, then printed in reverse. Input: n m, the m edges, then the nodes x and y.

Complexitate
O(n²) cu matricea de adiacență
Clasa
Clasa a XI-a (Grade 11)

Exemple

Exemplul 1

Intrare

6 7
1 2
1 3
2 4
3 4
4 5
3 6
6 5
1 5

Ieșire așteptată

3
1 2 4 5
Exemplul 2

Intrare

4 2
1 2
3 4
1 4

Ieșire așteptată

Nu exista lant

Codul C++

Codul complet, cu comentarii în română. Îl poți modifica liber și îl poți reseta oricând.

drum-minim-cu-bfs.cpp
/*
 * Titlu: Lanțul de lungime minimă între două noduri (BFS)
 * Clasa: 11
 * Capitol: Grafuri neorientate
 * Descriere: Lungimea unui lanț este numărul de muchii. Parcurgerea în lățime pornită din x
 *            descoperă nodurile în ordinea distanței față de x, deci prima dată când ajunge
 *            într-un nod o face pe un lanț de lungime minimă. Reținem dist[y] (distanța) și
 *            tata[y] (nodul din care a fost descoperit y). Lanțul se reface mergând din y
 *            prin tați până la x, apoi se afișează invers. Datele: n m, cele m muchii, apoi
 *            nodurile x și y.
 * Complexitate: O(n²) cu matricea de adiacență
 *
 * Exemplu
 * Intrare:
 * 6 7
 * 1 2
 * 1 3
 * 2 4
 * 3 4
 * 4 5
 * 3 6
 * 6 5
 * 1 5
 * Ieșire:
 * 3
 * 1 2 4 5
 *
 * Exemplu
 * Intrare:
 * 4 2
 * 1 2
 * 3 4
 * 1 4
 * Ieșire: Nu exista lant
 */
#include <iostream>
using namespace std;

int n, m, a[105][105], dist[105], tata[105], coada[105];

int main()
{
    int x, y;
    cin >> n >> m;
    for (int k = 1; k <= m; k++)
    {
        int u, v;
        cin >> u >> v;
        a[u][v] = a[v][u] = 1;
    }
    cin >> x >> y;

    for (int i = 1; i <= n; i++)
    {
        dist[i] = -1;
    }
    int inc = 1, sf = 1;
    coada[1] = x;
    dist[x] = 0;
    while (inc <= sf)
    {
        int u = coada[inc++];
        for (int v = 1; v <= n; v++)
        {
            if (a[u][v] == 1 && dist[v] == -1)
            {
                dist[v] = dist[u] + 1;
                tata[v] = u;
                coada[++sf] = v;
            }
        }
    }

    if (dist[y] == -1)
    {
        cout << "Nu exista lant\n";
        return 0;
    }
    cout << dist[y] << '\n';
    int lant[105], k = 0;
    for (int v = y; v != x; v = tata[v])
    {
        lant[k++] = v;
    }
    lant[k++] = x;
    for (int i = k - 1; i >= 0; i--)
    {
        cout << lant[i] << ' ';
    }
    cout << '\n';
    return 0;
}

Rulează pe un g++ adevărat (C++17, -O2) prin Compiler Explorer. Programele trebuie să se termine repede: există o limită de timp.