300x250

1. 제목

- 백준 11403 경로 찾기

- BOJ 11403 경로 찾기

문제 링크 : 11403번: 경로 찾기 (acmicpc.net)


2. 문제 설명

 

경로 찾기 

 
시간 제한 메모리 제한 제출 정답 맞힌 사람 정답 비율
1 초 256 MB 34968 20419 14875 58.035%

문제

가중치 없는 방향 그래프 G가 주어졌을 때, 모든 정점 (i, j)에 대해서, i에서 j로 가는 경로가 있는지 없는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 정점의 개수 N (1 ≤ N ≤ 100)이 주어진다. 둘째 줄부터 N개 줄에는 그래프의 인접 행렬이 주어진다. i번째 줄의 j번째 숫자가 1인 경우에는 i에서 j로 가는 간선이 존재한다는 뜻이고, 0인 경우는 없다는 뜻이다. i번째 줄의 i번째 숫자는 항상 0이다.

출력

총 N개의 줄에 걸쳐서 문제의 정답을 인접행렬 형식으로 출력한다. 정점 i에서 j로 가는 경로가 있으면 i번째 줄의 j번째 숫자를 1로, 없으면 0으로 출력해야 한다.

예제 입력 1 복사

3
0 1 0
0 0 1
1 0 0

예제 출력 1 복사

1 1 1
1 1 1
1 1 1

예제 입력 2 복사

7
0 0 0 1 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 0 0
0 0 0 0 1 1 0
1 0 0 0 0 0 0
0 0 0 0 0 0 1
0 0 1 0 0 0 0

예제 출력 2 복사

1 0 1 1 1 1 1
0 0 1 0 0 0 1
0 0 0 0 0 0 0
1 0 1 1 1 1 1
1 0 1 1 1 1 1
0 0 1 0 0 0 1
0 0 1 0 0 0 0

출처

  • 문제를 만든 사람: baekjoon
  • 데이터를 추가한 사람: degurii

 


3. 풀이 과정

플로이드 워셜을 이용하면 쉽게 풀 수 있는 문제인데 DFS로도 풀 수 있는 문제였어요. 0번째 노드부터 DFS 탐색을 시작하는데 해당 노드에 방문 했을 때 갈 수 있는 경로가 있다면 계속 DFS 탐색을 하며 최종적으로 갈 수 있는 모든 경로를 찾을 수 있게 돼요. 첫번째 예제로 설명을 드리면 탐색 순서가 0 => 1 => 2 순서로 탐색을 하는것을 할수있어요.

예제1

 

예제 2에 3번노드의 탐색을 시각화 해볼게요.

 

 

이런 식으로 0번 노드부터 N-1번 노드까지 탐색을 하면 연결 여부를 알 수 있게 돼요.


4. 함수 설명

void reset() 잠기는 높이가 바뀔때마다 bfs 탐색을 다시 하기 위해서 visited을 초기화 해줘요.


5. 코드

#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
#define MAX 100 + 1
using namespace std;
int N;

vector<int>graph[MAX];
int visit[MAX];

void Reset()
{
    // memset(visit, 0, sizeof(visit)); 
    // 위코드와 같은 역할
    for (int i = 0; i < N; i++)
    {
        visit[i] = 0;
    }
}

void Dfs(int node) 
{
    stack<int> s;    
    s.push(node);

    while (!s.empty())
    {
        int cur = s.top();
        s.pop();

        // 해당 노드가 가지고 있는 경로만큼 탐색
        for (int i = 0; i < graph[cur].size(); i++)
        {
            // 이미 방문을 했다면 스킵하기
            if (visit[graph[cur][i]] == 1)
                continue;

            visit[graph[cur][i]] = 1;
            s.push(graph[cur][i]);
        }
    }
}
int main() 
{
    cin >> N;
    for (int i = 0; i < N; i++) 
    {
        for (int j = 0; j < N; j++) 
        {
            int path;
            cin >> path;
            // 해당 위치로 가는 경로가 있다면
            if (path == 1)
                graph[i].push_back(j);
        }
    }

    for (int i = 0; i < N; i++) 
    {
        // 각 노드마다 방문여부 초기화 해주고
        Reset();
        // 순서대로 방문가능한곳부터 dfs 탐색 시작
        Dfs(i);
        for (int j = 0; j < N; j++)
            cout << visit[j] << " ";
        cout << "\n";
    }
}
300x250