본문 바로가기
컴퓨터 이론/C언어 & 자료구조 & 알고리즘

31. 단절점

by 컴퓨터공부용 2023. 5. 10.

단절점이란?

그래프에서 단절점이란 그래프를 두 개 이상의 연결 요소로 분할하는데 필요한 정점이다.

즉, 단절점을 제거하면 그래프가 더 이상 연결되지 않거나, 두 개 이상의 연결 요소로 분할된다.


단절점 찾기

단절점을 찾기 위해서는 그래프를 탐색하면서 해당 정점을 제거했을 때 그래프가 분리되는지를 확인해야 한다.

DFS를 이용하여 단절점을 찾을 수 있다.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX_SIZE 100

int adj[MAX_SIZE][MAX_SIZE]; // 인접 행렬
bool visited[MAX_SIZE]; // 방문 여부 배열
int dfn[MAX_SIZE]; // 정점 발견 순서
int low[MAX_SIZE]; // 정점의 low 값
// n: 정점 개수, m: 간선 개수, time: 발견 시간
int n, m, time, root, child_cnt; 

void dfs(int cur, int parent) {
    visited[cur] = true;
    dfn[cur] = low[cur] = ++time;

    for (int i = 0; i < n; i++) {
        if (adj[cur][i]) {
            if (!visited[i]) { // i를 처음 방문한 경우
                if (cur == root) child_cnt++; // 루트일 경우 자식 수 증가

                dfs(i, cur);

                if (low[i] >= dfn[cur]) { // cur이 단절점인 경우
                    printf("%d ", cur);
                }
                low[cur] = low[cur] < low[i] ? low[cur] : low[i];
            }
            else if (i != parent) { // 역방향 간선
                low[cur] = low[cur] < dfn[i] ? low[cur] : dfn[i];
            }
        }
    }
}

void find_articulation_points() {
    for (int i = 0; i < n; i++) {
        if (!visited[i]) {
            root = i;
            child_cnt = 0;
            dfs(i, -1);

            if (child_cnt > 1) { // 루트의 자식이 2개 이상인 경우
                printf("%d ", root);
            }
        }
    }
}

int main() {
    // 정점 수와 간선 수 입력
    scanf("%d %d", &n, &m);

    // 연결되어 있는 간선 입력
    for (int i = 0; i < m; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        adj[u][v] = adj[v][u] = 1;
    }

    find_articulation_points();

    return 0;
}

DFS를 이용하여 각 정점을 방문하며, 방문 순서와 low 값 계산을 하고, 단절점을 찾는다.

루트가 단절점인지는 자식 수를 이용하여 판단한다.

'컴퓨터 이론 > C언어 & 자료구조 & 알고리즘' 카테고리의 다른 글

33. Kruskal 알고리즘  (0) 2023.05.11
32. 최소비용 신장 트리  (0) 2023.05.11
30. 그래프 표현 방법  (0) 2023.05.03
29. 그래프  (0) 2023.05.03
28. 승자트리와 패자트리  (0) 2023.05.02

댓글