문제 분석
첫 번째 단계(문제 요약 및 조건 파악)
방향 없는 그래프가 주어졌을때, 연결 요소의 개수를 구하기.
입력
- 정점의 개수 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일때 큰 값이므로, 인접 행렬을 사용한다.
코드 작성
최종 코드
importsysinput=sys.stdin.readline# n이 최댓값일 경우에 대비해 빠른 입력# RecursionError 방지용sys.setrecursionlimit(10**8)
defdfs(now): # 현재 노드fornxtinrange(n): # 다음 열ifgraph[now][nxt] andnotchk[nxt]: # 그래프로 갈 수 있고, 방문을 안 했을 경우chk[nxt] =True# 방문 체크dfs(nxt) # dfs 실행n, m=map(int, input().split())
# 인접 행렬(N X N 2차원 리스트)graph= [[0] *nfor_inrange(n)] # 0-based# 간선for_inrange(m):
u, v=map(lambdax: x-1, map(int, input().split())) # 1-based to 0-basedgraph[u][v] =1# 간선으로 연결된 노드임.graph[v][u] =1# 무방향==양방향# for i, row in enumerate(graph):# print(f'{i}: {row}')ans=0# 방문 체크용chk= [False] *nforiinrange(n):
ifnotchk[i]:
chk[i] =Trueans+=1dfs(i) # dfsprint(ans)아래 코드로 제출 하면 RecursionError 가 발생한다.
파이썬 기본 재귀 depth를 초과(10*3)했기 때문이다.
따라서, 최종 코드인 위에는 depth를 늘려주었다.
RecursionError 발생 코드
importsysinput=sys.stdin.readline# n이 최댓값일 경우에 대비해 빠른 입력defdfs(now): # 현재 노드fornxtinrange(n): # 다음 열ifgraph[now][nxt] andnotchk[nxt]: # 그래프로 갈 수 있고, 방문을 안 했을 경우chk[nxt] =True# 방문 체크dfs(nxt) # dfs 실행n, m=map(int, input().split())
# 인접 행렬(N X N 2차원 리스트)graph= [[0] *nfor_inrange(n)] # 0-based# 간선for_inrange(m):
u, v=map(lambdax: x-1, map(int, input().split())) # 1-based to 0-basedgraph[u][v] =1# 간선으로 연결된 노드임.graph[v][u] =1# 무방향==양방향# for i, row in enumerate(graph):# print(f'{i}: {row}')ans=0# 방문 체크용chk= [False] *nforiinrange(n):
ifnotchk[i]:
chk[i] =Trueans+=1dfs(i) # dfsprint(ans)
느낀점
그래프 문제는 dfs, bfs로 접근해야 함은 알겠는데 적절하게 인접리스트, 인접행렬을 선택해 푸는 것은 어려운 것 같다.
문제 분석
첫 번째 단계(문제 요약 및 조건 파악)
방향 없는 그래프가 주어졌을때, 연결 요소의 개수를 구하기.
입력
출력
두 번째 단계 (문제 핵심 파악)
방향 없는 그래프는 즉, 순환성 그래프이다.
연결 요소는 그래프 별로 덩어리로 되어있기 때문에, 모든 노드를 방문해주어야 함(이때 탐색 순서는 상관이 없음.)
그래프 표현시→ 인접 행렬 or 인접 리스트(인접 리스트(희소), 인접 행렬(밀집))
이때 최대 간선의 개수가 N×(N-1)/2인데, 이 값은 큰 값(밀집)인가 작은 값(희소)인가?
u ≠ v이므로 nC2임. nC2는 수식으로 N×(N-1)/2이다. 이는 N이 1000일때 큰 값이므로,
인접 행렬을 사용한다.코드 작성
최종 코드
아래 코드로 제출 하면
RecursionError가 발생한다.파이썬 기본 재귀 depth를 초과(10*3)했기 때문이다.
따라서, 최종 코드인 위에는 depth를 늘려주었다.
RecursionError 발생 코드
느낀점
그래프 문제는 dfs, bfs로 접근해야 함은 알겠는데 적절하게 인접리스트, 인접행렬을 선택해 푸는 것은 어려운 것 같다.