9-2) 경로 탐색(인접 행렬)

김예지·2021년 9월 8일
0

문제


방향그래프가 주어지면 1번 정점에서 N번 정점으로 가는 모든 경로의 가지 수를 출력하는 프로그램을 작성하세요. 아래 그래프에서 1번 정점에서 5번 정점으로 가는 가지 수는
12345
125
13425
1345
1425
145
총 6 가지입니다.

[입력설명]
첫째 줄에는 정점의 수 N(1<=N<=20)와 간선의 수 M가 주어진다. 그 다음부터 M줄에 걸쳐 연 결정보가 주어진다.
[출력설명]
총 가지수를 출력한다.

입력예제 1

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

출력예제 1

6


문제 풀이

예습이론

  • 인접행렬은, 노드의 개수가 적을 때 사용할 수 있는 방법이다. 만약 노드의 개수가 많다면 인접행렬이아닌 인접그래프 방식을 이용한다.(다음문제 참고)
  • Array.from(Array(n+1), ()=>Array(n+1).fill(0))는 행이 n+1개, 열이 n+1개인 유사배열을 만든다. 아래 코드에서 행과 열의 개수를 n+1으로 설정한 이유는, 인덱스 1번부터 사용하기 위해서이다.(0번 비워둠)

코드

  • DFS로 풀이할 수 있는 문제이다. 인접행렬 graph를 만들어주고, 방문한 노드인지 체크하기 위해 ch배열을 만든다.
  • graph[v][i]===1의 의미는 v에서 i로 이동할 수 있다는 뜻이다. 무조건 1번에서 시작하기 때문에 초기코드가 DFS(1)이다. 이로인해 DFS(1)에서 graph[1][i]가 되는데, 이는 1에서 i로 이동할 수 있는지 체크한다.
    같은 원리로 path.push(i)를 하면, DFS(i)를 해준다. i부터 출발한다는 의미이다.
  • 코드 전체 풀이 원리는 다음과 같다.
<html>
    <head>
        <meta charset="UTF-8">
        <title>출력결과</title>
    </head>
    <body>
        <script>
            //n: 정점 갯수, arr:간선 정보
            function solution(n, arr){  
                let answer=0;
                let graph=Array.from(Array(n+1), ()=>Array(n+1).fill(0)); //graph: 인접행렬을 만들 2차원 배열
                let ch=Array.from({length:n+1}, ()=>0);
                path=[]; //테스트 코드 path(경로)
                //인접 행렬
                for(let [a, b] of arr){
                  //console.log(a, b);
                  graph[a][b]=1; //방향그래프
                }
                function DFS(v){
                  if(v===n){
                    answer++;
                    console.log(path);
                  }
                  else{
                    //가지뻗기
                    for(let i=1; i<=n; i++){
                      //v->i로 이동할 수 있고 ~
                      if(graph[v][i]===1 && ch[i]===0){
                        ch[i]=1;
                        path.push(i);
                        DFS(i); //2를 넣었으면, D(2)가 됨(출발을 2부터 함)
                        ch[i]=0;
                        path.pop(); //back 할 때 
                      }
                    }
                  }
                }
                path.push(1); //출발점 1은 무조건 처음에 push
                ch[1]=1; //출발점은 무조건 1 처리해주기(안하면 오류남. 없애보기)
                DFS(1);
                return answer; 
            }

            let arr=[[1, 2], [1, 3], [1, 4], [2, 1], [2, 3], [2, 5], [3, 4], [4, 2], [4, 5]];
            console.log(solution(5, arr));
        </script>
    </body>
</html>

profile
내가 짱이다 😎 매일 조금씩 성장하기🌱

2개의 댓글

comment-user-thumbnail
2021년 9월 18일

9/18
체크 반드시 해줘야함

답글 달기
comment-user-thumbnail
2021년 9월 23일

9/23
for(let i=2; i<=n; i++)으로 해도 됨. 1은 무조건 출발할때 체크되니까!

답글 달기