Clasa a XI-a · Grafuri neorientateRead in English

Componentele conexe în C++

În engleză: Connected components

O(n²)C++1778 de linii1 exemplu

Ideea

Un graf este conex dacă între oricare două noduri există un lanț. O componentă conexă este o „bucată” conexă maximală a grafului. Luăm nodurile în ordine; din fiecare nod încă nevizitat pornim o parcurgere DFS, iar toate nodurile atinse primesc același număr de componentă. Numărul de parcurgeri pornite este numărul de componente (graful e conex dacă iese 1). Se afișează numărul de componente și nodurile fiecăreia, în ordine crescătoare.

Descrierea în engleză

A graph is connected if there is a path between any two nodes. A connected component is a maximal connected 'piece' of the graph. We take the nodes in order; from every node not yet visited we start a DFS traversal, and all nodes reached receive the same component number. The number of traversals started is the number of components (the graph is connected if it is 1). The number of components and the nodes of each, in increasing order, are printed.

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

Exemple

Exemplul 1

Intrare

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

Ieșire așteptată

3
1 4 6
2 3 7 8
5

Codul C++

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

componente-conexe.cpp
/*
 * Titlu: Componentele conexe
 * Clasa: 11
 * Capitol: Grafuri neorientate
 * Descriere: Un graf este conex dacă între oricare două noduri există un lanț. O componentă
 *            conexă este o „bucată” conexă maximală a grafului. Luăm nodurile în ordine; din
 *            fiecare nod încă nevizitat pornim o parcurgere DFS, iar toate nodurile atinse
 *            primesc același număr de componentă. Numărul de parcurgeri pornite este
 *            numărul de componente (graful e conex dacă iese 1). Se afișează numărul de
 *            componente și nodurile fiecăreia, în ordine crescătoare.
 * Complexitate: O(n²) cu matricea de adiacență
 *
 * Exemplu
 * Intrare:
 * 8 5
 * 1 4
 * 4 6
 * 2 7
 * 3 8
 * 8 2
 * Ieșire:
 * 3
 * 1 4 6
 * 2 3 7 8
 * 5
 */
#include <iostream>
using namespace std;

int n, m, a[105][105], comp[105];

void dfs(int x, int c)
{
    comp[x] = c;
    for (int y = 1; y <= n; y++)
    {
        if (a[x][y] == 1 && comp[y] == 0)
        {
            dfs(y, c);
        }
    }
}

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

    int nrComp = 0;
    for (int i = 1; i <= n; i++)
    {
        if (comp[i] == 0)
        {
            nrComp++;
            dfs(i, nrComp);
        }
    }

    cout << nrComp << '\n';
    for (int c = 1; c <= nrComp; c++)
    {
        for (int i = 1; i <= n; i++)
        {
            if (comp[i] == c)
            {
                cout << 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.