← Назад к графовым алгоритмам

Поиск мостов

Нахождение рёбер, удаление которых увеличивает число компонент связности

🐍 Python
n, m = map(int, input().split())
G = [[] for _ in range(n)]

for _ in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    G[a].append(b)
    G[b].append(a)

used = [0] * n
T = [0] * n      # Время входа
L = [0] * n      # Минимальное достижимое время
B = []           # Мосты
t = 0            # Текущее время

def dfs(h, p):
    global t
    used[h] = 1
    T[h] = t
    L[h] = t
    t += 1
    for a in G[h]:
        if not used[a]:
            dfs(a, h)
            L[h] = min(L[h], L[a])
            if L[a] > T[h]:
                B.append([h + 1, a + 1])
        elif a != p:
            L[h] = min(L[h], T[a])

for i in range(n):
    if not used[i]:
        dfs(i, -1)

for b in B:
    print(*b)
⚙️ C++
#include <bits/stdc++.h>
using namespace std;

vector<vector<int>> G;
vector<int> used, T, L;
vector<pair<int, int>> bridges;
int t = 0;

void dfs(int h, int p) {
    used[h] = 1;
    T[h] = t;
    L[h] = t;
    t++;
    
    for (int a : G[h]) {
        if (!used[a]) {
            dfs(a, h);
            L[h] = min(L[h], L[a]);
            if (L[a] > T[h]) {
                bridges.push_back({h, a});
            }
        } else if (a != p) {
            L[h] = min(L[h], T[a]);
        }
    }
}

int main() {
    int n, m;
    cin >> n >> m;
    
    G.resize(n);
    used.assign(n, 0);
    T.resize(n);
    L.resize(n);
    
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        a--; b--;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i, -1);
        }
    }
    
    for (auto [a, b] : bridges) {
        cout << a + 1 << " " << b + 1 << "\n";
    }
    
    return 0;
}

Как работает алгоритм поиска мостов (Тарьяна)?

Мост — это ребро, удаление которого увеличивает количество компонент связности в графе. Алгоритм Тарьяна находит все мосты за один обход DFS.

Основная идея: ребро (h, a) является мостом, если L[a] > T[h], где:

Шаги алгоритма:

Условие L[a] > T[h] означает, что из поддерева вершины a нет обратного ребра, ведущего выше вершины h, поэтому удаление ребра разорвёт граф.

Временная сложность: O(n + m), где n — количество вершин, m — количество рёбер.

Пространственная сложность: O(n + m).

Формат ввода и вывода

Ввод:

Вывод:

Пример ввода:

4 4
1 2
2 3
3 4
2 4

Здесь:
n=4, m=4
Рёбра: 1-2, 2-3, 3-4, 2-4

Вывод:
1 2

Ребро 1-2 — мост, так как его удаление отделит вершину 1 от остальных.

Попробовать поиск мостов онлайн

Введите неориентированный граф в формате, описанном выше:

Результат появится здесь...