Нахождение рёбер, удаление которых увеличивает число компонент связности
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)
#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).
Ввод:
n m — количество вершин и количество рёберa b — ребро между вершинами a и b (повторяется 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 от остальных.
Введите неориентированный граф в формате, описанном выше: