포스트

24479 알고리즘 수업 - 깊이 우선 탐색 1

24479 알고리즘 수업 - 깊이 우선 탐색 1

깊이 우선 탐색의 가장 기초

그런데 입력량이 많아 시간초과에 주의할 것

1. 문제


https://www.acmicpc.net/problem/24479

간단 설명

깊이 우선 탐색 방법의 가장 기초 구현

노드를 방문하면서, 방문한 순서를 기록하고

마지막에 몇번째 방문했는지 출력하는 문제

2. 문제 분석


알고리즘

1
2
3
4
5
6
7
8
9
10
1. N, M, R을 입력받고, 연결리스트 백터의 사이즈를 조절한다
2. M개의 간선 정보를 입력받는다. 이때 무방향 간선이므로 양방향으로 삽입해준다
3. 연결리스트의 원소를 정렬해준다.(오름차순으로 방문예정이므로)
4. 노드 R부터 시작하여 DFS을 시작한다
    4-1. 현재 노드를 방문 처리한다
    4-2. 결과 배열에 이 노드가 몇번째 방문인지 기록한다
    4-3. 이 노드와 연결된 노드를 연결리스트를 통해 확인한다
    4-4. 존재하면 이 노드번호를 이용해 DFS를 호출한다 
    4-5. 연결된 모든 노드를 방문할때까지 4번을 반복한다
5. 1~N번 노드의 방문 순서를 출력한다

필요변수

노드 개수 N, 간선 개수 M, 시작 노드 N

연결 리스트를 구현할 2중 벡터 vector<vector<int>>

각 노드의 방문 여부를 기록할 visited 배열

각 노드가 몇번째 방문인지 기록할 result 배열

주의점

  • 인접 정점을 오름차순으로 방문해야한다
  • 입력량이 많으므로 cin, cout으로 입력받을시 시간초과에 주의할 것

3. 소스코드

1
2
3
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

를 이용해 C++ cin, cout 속도를 높이는 방법도 있지만,

나는 scanf, printf를 이용했다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define MAX 100005

int N, M, R;
vector< vector<int> > graph;
int result[MAX];
int visited[MAX];
int cnt = 0;

void DFS(int now) {
	if (visited[now] == 1) return; // 이미 방문한 노드라면 종료

	visited[now] = 1;
	result[now] = ++cnt; // 몇번째 방문인지 기록해둠

	// 현재 노드와 연결된 노드를 찾아 다음 DFS 호출
	for(int i=0; i<graph[now].size(); i++)
		DFS(graph[now][i]);

	// 원복시키지 않아도 상관없음 한번 방문하면 끝임. 
	// visited[now] = 0;

}

int main() {
	freopen_s(new FILE*, "input.txt", "r", stdin);
	scanf("%d %d %d", &N, &M, &R);
	// cin >> N >> M >> R;

	graph.resize(N + 1); // 연결리스트 벡터를 N+1로 리사이즈

	// 1. 입력
	for (int i = 0; i < M; i++) {
		int start, end;
		scanf("%d %d", &start, &end);
		// cin >> start >> end;

		graph[start].push_back(end);
		graph[end].push_back(start);
	}

	// 2. 연결 리스트의 원소를 정렬
	for (int i = 1; i <= N; i++) {
		sort(graph[i].begin(), graph[i].end());
	}

	// 3. 시작 원소 R부터 DFS 시작
	DFS(R);

	// 4. result 배열에 저장된 숫자 출력
	for (int i = 1; i <= N; i++) {
		printf("%d\n", result[i]);
		// cout << result[i] << endl;
	}

	return 0;
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.