Skip to content

BOJ 11724 연결 요소의 개수 풀이 #7

Description

@allzeroyou

문제 분석

첫 번째 단계(문제 요약 및 조건 파악)

방향 없는 그래프가 주어졌을때, 연결 요소의 개수를 구하기.

입력

  • 정점의 개수 N, 간선의 개수 M(1 ≤ N ≤ 1,000, 0 ≤ M ≤ N×(N-1)/2)
  • M개의 줄에 간선의 양 끝점 u, v가 주어짐(1 ≤ u, v ≤ N, u ≠ v)
  • 같은 간선은 한 번만 주어짐.

출력

  • 연결 요소의 개수 출력

두 번째 단계 (문제 핵심 파악)

방향 없는 그래프는 즉, 순환성 그래프이다.

연결 요소는 그래프 별로 덩어리로 되어있기 때문에, 모든 노드를 방문해주어야 함(이때 탐색 순서는 상관이 없음.)

그래프 표현시→ 인접 행렬 or 인접 리스트(인접 리스트(희소), 인접 행렬(밀집))

이때 최대 간선의 개수가 N×(N-1)/2인데, 이 값은 큰 값(밀집)인가 작은 값(희소)인가?

u ≠ v이므로 nC2임. nC2는 수식으로 N×(N-1)/2이다. 이는 N이 1000일때 큰 값이므로, 인접 행렬을 사용한다.

코드 작성

최종 코드

import sys

input = sys.stdin.readline  # n이 최댓값일 경우에 대비해 빠른 입력
# RecursionError 방지용
sys.setrecursionlimit(10 ** 8)

def dfs(now):  # 현재 노드
    for nxt in range(n):  # 다음 열
        if graph[now][nxt] and not chk[nxt]:  # 그래프로 갈 수 있고, 방문을 안 했을 경우
            chk[nxt] = True  # 방문 체크
            dfs(nxt)  # dfs 실행

n, m = map(int, input().split())
# 인접 행렬(N X N 2차원 리스트)
graph = [[0] * n for _ in range(n)]  # 0-based
# 간선
for _ in range(m):
    u, v = map(lambda x: x - 1, map(int, input().split()))  # 1-based to 0-based
    graph[u][v] = 1  # 간선으로 연결된 노드임.
    graph[v][u] = 1  # 무방향==양방향

# for i, row in enumerate(graph):
#     print(f'{i}: {row}')

ans = 0
# 방문 체크용
chk = [False] * n

for i in range(n):
    if not chk[i]:
        chk[i] = True
        ans += 1
        dfs(i)  # dfs
print(ans)

아래 코드로 제출 하면 RecursionError 가 발생한다.

파이썬 기본 재귀 depth를 초과(10*3)했기 때문이다.

따라서, 최종 코드인 위에는 depth를 늘려주었다.

RecursionError 발생 코드

import sys

input = sys.stdin.readline  # n이 최댓값일 경우에 대비해 빠른 입력

def dfs(now):  # 현재 노드
    for nxt in range(n):  # 다음 열
        if graph[now][nxt] and not chk[nxt]:  # 그래프로 갈 수 있고, 방문을 안 했을 경우
            chk[nxt] = True  # 방문 체크
            dfs(nxt)  # dfs 실행

n, m = map(int, input().split())
# 인접 행렬(N X N 2차원 리스트)
graph = [[0] * n for _ in range(n)]  # 0-based
# 간선
for _ in range(m):
    u, v = map(lambda x: x - 1, map(int, input().split()))  # 1-based to 0-based
    graph[u][v] = 1  # 간선으로 연결된 노드임.
    graph[v][u] = 1  # 무방향==양방향

# for i, row in enumerate(graph):
#     print(f'{i}: {row}')

ans = 0
# 방문 체크용
chk = [False] * n

for i in range(n):
    if not chk[i]:
        chk[i] = True
        ans += 1
        dfs(i)  # dfs
print(ans)

11724

느낀점

그래프 문제는 dfs, bfs로 접근해야 함은 알겠는데 적절하게 인접리스트, 인접행렬을 선택해 푸는 것은 어려운 것 같다.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions