Нахождение вершин, удаление которых увеличивает число компонент связности
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 # Минимальное достижимое время
A = [] # Точки сочленения
t = 0 # Текущее время
def dfs(h, p):
global t
used[h] = 1
T[h] = t
L[h] = t
t += 1
c = 0
f = 0
for a in G[h]:
if not used[a]:
c += 1
dfs(a, h)
L[h] = min(L[h], L[a])
if L[a] >= T[h] and p != -1:
f = 1
elif a != p:
L[h] = min(L[h], T[a])
if p == -1 and c >= 2:
f = 1
if f:
A.append(h + 1)
for i in range(n):
if not used[i]:
dfs(i, -1)
print(*A)
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> G;
vector<int> used, T, L;
vector<int> articulationPoints;
int t = 0;
void dfs(int h, int p) {
used[h] = 1;
T[h] = t;
L[h] = t;
t++;
int c = 0;
bool f = false;
for (int a : G[h]) {
if (!used[a]) {
c++;
dfs(a, h);
L[h] = min(L[h], L[a]);
if (L[a] >= T[h] && p != -1) {
f = true;
}
} else if (a != p) {
L[h] = min(L[h], T[a]);
}
}
if (p == -1 && c >= 2) {
f = true;
}
if (f) {
articulationPoints.push_back(h + 1);
}
}
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 (int v : articulationPoints) {
cout << v << " ";
}
return 0;
}
Точка сочленения — это вершина, удаление которой увеличивает количество компонент связности в графе. Алгоритм Тарьяна находит все точки сочленения за один обход DFS.
Основная идея: вершина h является точкой сочленения, если выполнено одно из условий:
Здесь:
Шаги алгоритма:
Временная сложность: O(n + m), где n — количество вершин, m — количество рёбер.
Пространственная сложность: O(n + m).
Ввод:
n m — количество вершин и количество рёберa b — ребро между вершинами a и b (повторяется m раз)Вывод:
6 7
1 2
1 3
2 3
2 4
4 5
4 6
5 6
Здесь:
n=6, m=7
Граф: треугольник 1-2-3, и компонента 4-5-6, соединённая ребром 2-4
Вывод:
2 4
Вершины 2 и 4 — точки сочленения (удаление 2 оторвёт треугольник от компоненты, удаление 4 оторвёт 5-6 от 4)
Введите неориентированный граф в формате, описанном выше: