3 분 소요

문제

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

다시 푸는 이유

컴퓨터가 이해할 수 있는 그래프 표현은 인접 행렬이나 인접 리스트를 사용한다. 이전 문제 풀이에서는 인접 행렬을 사용했기 때문에 이번에는 인접 리스트를 사용해서 그래프를 표현할 것이다.


그래프 표현

  • 인접 리스트를 사용할 방법으로 베열 Vector를 사용한다.
  • 여기서 고려할 점은 배열 크기가 N이면 인덱스는 0 ~ N-1로 표현된다.
  • 문제에서 “정점 번호는 1번부터 N번까지”라고 명시했기 때문에 인덱스 0을 제외하고 1부터 N까지 표현하기 위해서 배열 크기를 N+1로 한다.
  • 그리고 문제에서 “정점의 개수 N(1 ≤ N ≤ 1,000)”이기 때문에 배열 크기는 1001 이다.
vector<int> map[1001]; // 인접 리스트로 그래프 표현
int visited[1001]; // 현재 방문한 정점

// ~~중략~~ 

// 간선 연결
for (int i = 0; i < M; i++) {

		cin >> v1 >> v2;

		map[v1].push_back(v2);
		map[v2].push_back(v1);
}


DFS

void DFS(int v) {
	visited[v] = 1; // 현재 방문한 노드 기록
	cout << v << " "; // 방문 노드 출력

	// 현재 노드에 연결되었고 방문하지 않은 노드를 재귀호출
	for (int i = 0; i < map[v].size(); i++) {
		int x = map[v][i]; // 연결 정점
		if (visited[x] == 0)
			DFS(x);
	}
}


BFS

void BFS(int v) {
	queue<int> q; // BFS에 사용할 큐 생성
	q.push(v); // 시작 노드 큐에 삽입

	// 방문할 노드가 없을 때까지 반복
	while (!q.empty()) {
		int next = q.front(); // 탐색할 노드
		visited[next] = 1; // 현재 방문한 노드 기록
		cout << next << " "; // 현재 노드 출력
		q.pop(); // 방문한 노드 큐에서 제거

		// 현재 노드에 연결되었고, 방문하지 않은 노드를 큐에 삽입
		for (int i = 0; i < map[next].size(); i++) {
			int x = map[next][i]; // 연결 정점
			if (visited[x] == 0) {
				q.push(x); // 다음 방문할 노드 삽입
				visited[x] = 1; // 중복 노드 삽입 방지를 위해 미리 기록
			}

		}
	}
}


전체 코드

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> map[1001]; // 인접 리스트로 그래프 표현
int N; // 노드의 개수
int M; // 간선의 개수
int V;  // 탐색을 시작할 정점의 번호
int visited[1001]; // 현재 방문한 정점

// 방문 초기화 함수
void reset() {
	for (int i = 1; i <= N; i++)
		visited[i] = 0;
}

// DFS 수행 함수
void DFS(int v) {
	visited[v] = 1; // 현재 방문한 노드 기록
	cout << v << " "; // 방문 노드 출력

	// 현재 노드에 연결되었고 방문하지 않은 노드를 재귀호출
	for (int i = 0; i < map[v].size(); i++) {
		int x = map[v][i]; // 연결 정점
		if (visited[x] == 0)
			DFS(x);
	}
}

// BFS 수행 함수
void BFS(int v) {
	queue<int> q; // BFS에 사용할 큐 생성
	q.push(v); // 시작 노드 큐에 삽입

	// 방문할 노드가 없을 때까지 반복
	while (!q.empty()) {
		int next = q.front(); // 탐색할 노드
		visited[next] = 1; // 현재 방문한 노드 기록
		cout << next << " "; // 현재 노드 출력
		q.pop(); // 방문한 노드 큐에서 제거

		// 현재 노드에 연결되었고, 방문하지 않은 노드를 큐에 삽입
		for (int i = 0; i < map[next].size(); i++) {
			int x = map[next][i]; // 연결 정점
			if (visited[x] == 0) {
				q.push(x); // 다음 방문할 노드 삽입
				visited[x] = 1; // 중복 노드 삽입 방지를 위해 미리 기록
			}

		}
	}
}

int main() {

	// 노드의 개수, 간선의 개수, 시작 정점 입력
	cin >> N >> M >> V;

	int v1, v2; // 연결할 노드

	// 간선 연결
	for (int i = 0; i < M; i++) {

		cin >> v1 >> v2;

		map[v1].push_back(v2);
		map[v2].push_back(v1);
	}

	// 정점 번호가 작은 것을 먼저 방문하게 하기 위한 작업
	for (int i = 1; i <= N; i++)
		sort(map[i].begin(), map[i].end());

	//DFS 수행
	DFS(V);

	// rest 수행
	reset();
	cout << "\n";

	//BFS 수행
	BFS(V);

	return 0;
}


참조

카테고리:

업데이트: