소프트웨어 개발/알고리즘 풀이하자!

[백준 1260번 / C++] DFS와 BFS

밍Z 2021. 2. 23. 18:12

백준 1260번 "DFS와 BFS" 문제 풀이입니다.

 

해당 문제 링크

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

1260번: DFS와 BFS

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사

www.acmicpc.net

 

문제

그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.

입력

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.

 

출력

첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. V부터 방문된 점을 순서대로 출력하면 된다.

 

[예제 입력 1]

4 5 1 (정점 갯수, 간선 갯수, 시작 정점)
1 2
1 3
1 4
2 4
3 4

 

[예제 출력 1]

1 2 4 3 (DFS 순서)
1 2 3 4 (BFS 순서)

 

[예제 입력 2]

5 5 3
5 4
5 2
1 2
3 4
3 1

 

[예제 출력 2]

3 1 2 5 4
3 1 4 2 5

 

[예제 입력 3]

1000 1 1000
999 1000

 

[예제 출력 3]

1000 999 
1000 999

개인적인 풀이

 

1. 먼저 필요한 변수, 벡터 등을 선언해 줍니다.

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define MAX 1001

using namespace std;

// 정점 갯수, 간선 갯수, 시작 정점
int N, M, V;
// 방문 여부
int visited[MAX];

vector<int> graph[MAX];

 

2. 입력값을 처리해 주고, graph 벡터를 각각 정점들에 대해서 오름차순 정렬시켜 줍니다.

void input() {
    cin >> N >> M >> V;
	
    for (int m=0; m<M; ++m) {
        int p,q;
        cin >> p >> q;
        
        // 각 정점마다 연결된 정점들을 각 벡터에 저장
        graph[p].push_back(q);
        graph[q].push_back(p);
    }
    
    for (int n=1; n<=N; ++n) {
        // 벡터를 오름차순으로 정렬
        sort(graph[n].begin(), graph[n].end(), less<int>());
    }
}

 

3. 방문 여부 판단하는 배열은 dfs가 끝난 뒤, 초기화해야 합니다.

void init() {
    for (int n=1; n<=N; ++n) {
        // 방문하지 않은 상태(false)로 만들기
        visited[n] = 0;
    }
}

 

4. 파라미터를 시작 정점으로 갖는 dfs 함수를 작성합니다.

void dfs(int v) {
    cout << v << " ";

    // 시작 정점에 연결된 정점들 중에서
    // 방문하지 않은 정점이 있으면 방문! (작은 숫자부터)
    for (int n=0; n<graph[v].size(); ++n) {
        int nv = graph[v][n];
        if (!visited[nv]) {
            // 방문 표시하고, dfs 이동
            visited[nv] = 1;
            dfs(nv);
        }
    }
}

 

5. 파라미터를 시작 정점으로 갖는 bfs 함수도 작성합니다.

void bfs(int v) {
    queue<int> que;
    que.push(v);
    
    // queue가 비어있지 않으면 계속 진행
    while (!que.empty()) {
        // 가장 앞에 있는 정점 pop
        int f = que.front();
        cout << f << " ";
        que.pop();
        
        // nv에 연결되어 있는 방문하지 않은 정점들 다 que에 넣기
        for (int n=0; n<graph[f].size(); ++n) {
            int nv = graph[f][n];
            if (!visited[nv]) {
                que.push(nv);
                // 방문 표시
                visited[nv] = 1;
            }      
        }
    }
}

 

6. 마지막으로 main 함수를 작성!

int main(void) {
    input();

    visited[V] = 1;
    dfs(V);
    cout << endl;

    init();
    visited[V] = 1;
    bfs(V);
    cout << endl;
    return 0;
}

 


 

[전체 코드]

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define MAX 1001

using namespace std;

// 정점 갯수, 간선 갯수, 시작 정점
int N, M, V;
// 방문 여부
int visited[MAX];

vector<int> graph[MAX];

void input() {
    cin >> N >> M >> V;
	
    for (int m=0; m<M; ++m) {
        int p,q;
        cin >> p >> q;
        
        // 각 정점마다 연결된 정점들을 각 벡터에 저장
        graph[p].push_back(q);
        graph[q].push_back(p);
    }

    for (int n=1; n<=N; ++n) {
        // 벡터를 오름차순으로 정렬
        sort(graph[n].begin(), graph[n].end(), less<int>());
    }
}

void init() {
    for (int n=1; n<=N; ++n) {
        // 방문하지 않은 상태(false)로 만들기
        visited[n] = 0;
    }
}

void dfs(int v) {
    cout << v << " ";

    // 시작 정점에 연결된 정점들 중에서
    // 방문하지 않은 정점이 있으면 방문! (작은 숫자부터)
    for (int n=0; n<graph[v].size(); ++n) {
        int nv = graph[v][n];
        if (!visited[nv]) {
            // 방문 표시하고, dfs 이동
            visited[nv] = 1;
            dfs(nv);
        }
    }
}

void bfs(int v) {
    queue<int> que;
    que.push(v);
    
    // queue가 비어있지 않으면 계속 진행
    while (!que.empty()) {
        // 가장 앞에 있는 정점 pop
        int nv = que.front();
        cout << nv << " ";
        que.pop();
        
        // nv에 연결되어 있는 방문하지 않은 정점들 다 que에 넣기
        for (int n=0; n<graph[nv].size(); ++n) {
            int nnv = graph[nv][n];
            if (!visited[nnv]) {
                que.push(nnv);
                // 방문 표시
                visited[nnv] = 1;
            }      
        }
    }
}

int main(void) {
    input();

    visited[V] = 1;
    dfs(V);
    cout << endl;

    init();
    visited[V] = 1;
    bfs(V);
    cout << endl;
    return 0;
}