[BAEKJOON] 1260 DFS와 BFS - python, c
그래프의 정점, 간선 수와 방문 시작점을 입력받는다.
간선 수의 개수만큼 연결된 두 정점을 입력받는다. 이후 시작점부터 그래프를 순회하는데 dfs와 bfs의 방법으로 순회를 하면 된다.
DFS와 BSF에 관련한 포스트는 조만간 올릴 수 있도록 하겠다.
dfs와 bfs의 핵심은 visit 체크를 해 주는 것이다. 내가 다음에 가려는 위치가 맞는지 파악하고, 이 위치에 지난번에 간 적 없으면 현재 위치를 다음번의 위치로 이동시킨다.
이 문제에서는 정점의 번호를 1번부터 n번까지 받게 된다. 이 경우 리스트에 접근할 때 [n-1]과 같은 방식으로 할 수 있는데, 이렇게 되면 한번씩 실수할 수 있는 가능성이 올라간다. 이것을 최소화 하기 위해 배열의 사이즈를 n+1만큼 잡아 Map[n]에 접근할 수 있도록 한다.
python에서는 리스트의 크기를 자유롭게 지정할 수 있기 때문에 크기에 대해 생각할 필요가 없지만,
c에서는 배열의 크기를 먼저 지정해주어야 한다. 이 경우, 아주 큰 배열에 맞추게 되면 작은 배열을 생성해야 할 때 큰 메모리 손실이 일어나게 되며, 이를 막기 위해 동적할당으로 배열을 준다.
-
python
def DFS(v): for i in range(1, n+1): # 방문한 적이 없고, 연결된 간선이 있는 정점이면 if not visited_dfs[i] and Map[v][i]: # 방문처리를 한다. visited_dfs[i] = 1 result_dfs.append(i) # 이 정점을 중심으로 연결된 다른 정점을 찾으러 재귀. DFS(i) def BFS(v): result = [] # BFS에서는 방문해야 할 리스트를 Q에 넣고, 동시에 방문처리를 한다. Q = [v] visited_bfs[v] = 1 # 방문해야 할 리스트가 사라질 때 까지 반복 while Q: # 현재 방문한 정점을 now로 받고, 결과 리스트에 append한다. now = Q.pop(0) result.append(now) for i in range(1, n+1): # 방문한 적이 없고, 연결된 간선이 있는 정점이면 if not visited_bfs[i] and Map[now][i]: # 방문해야 할 리스트(Q)에 넣고 방문처리한다. Q.append(i) visited_bfs[i] = 1 return result n, m, v = list(map(int, input().split())) Map = [[0 for i in range(n+1)] for j in range(n+1)] visited_dfs = [0 for i in range(n+1)] result_dfs = [] visited_bfs = [0 for i in range(n+1)] for i in range(m): x, y = list(map(int, input().split())) Map[x][y] = 1 Map[y][x] = 1 visited_dfs[v] = 1 result_dfs.append(v) DFS(v) print(' '.join(map(str, result_dfs))) print(' '.join(map(str, BFS(v))))
-
c
#include <stdio.h> #include <malloc.h> int n, m, v; int **Map; int x, y; int *dfs_visit; int *bfs_visit; int *Q; int rp, wp; void DFS(int v) { for (int i = 1; i <= n; i++) { // 방문한 적이 없고, 연결된 간선이 있는 정점이면 if (Map[v][i] == 1 && dfs_visit[i] != 1) { // 방문처리를 하고 정점을 출력. dfs_visit[i] = 1; printf("%d ", i); // 그 정점으로 연결된 다른 정점들을 찾기위해 재귀 DFS(i); } } } void BFS(int v) { int now; Q[wp++] = v; bfs_visit[v] = 1; while (rp < wp) { now = Q[rp++]; printf("%d ", now); for (int i = 1; i <= n; i++) { // 방문한 적이 없고, 연결된 간선이 있는 정점이면 if (Map[now][i] == 1 && bfs_visit[i] != 1) { // 방문해야 할 리스트에 넣고, 방문처리. Q[wp++] = i; bfs_visit[i] = 1; } } } } int main(void) { freopen("1260_input.txt", "r", stdin); scanf("%d %d %d", &n, &m, &v); // Map은 2차원 배열을 동적할당 하기 위해 n + 1개의 1차원 배열을 n + 1 사이즈의 배열에 각각 연결한다. Map = (int**)malloc(sizeof(int*) * (n + 1)); dfs_visit = (int*)malloc(sizeof(int) * (n + 1)); bfs_visit = (int*)malloc(sizeof(int) * (n + 1)); // Q는 방문해야 하는 정점 리스트이기 때문에 문제에 따라 좀 더 여유있게 잡아주는 것이 좋다. Q = (int*)malloc(sizeof(int)*(2 * n)); for (int i = 1; i <= n; i++) { Map[i] = (int*)malloc(sizeof(int) * (n + 1)); } for (int cnt = 0; cnt < m; cnt++) { scanf("%d %d", &x, &y); Map[x][y] = 1; Map[y][x] = 1; } dfs_visit[v] = 1; printf("%d ", v); DFS(v); // BFS에서는 append와 pop이 자유롭지 않기 때문에 read point와 write point 각각을 rp, wp로 두어 사용한다. rp = wp = 0; printf("\n"); BFS(v); // 동적할당으로 사용한 배열들의 메모리를 해제해준다. for (int i = 0; i < n + 1; i++) { free(Map[i]); } free(Map); free(dfs_visit); free(bfs_visit); free(Q); return 0; }