728x90
반응형

문제

N*M의 배열에서 (0,0) 에서 (N-1,M-1)까지 가는 최단거리를 구하여라

 

입력예제

첫째줄 N 과 M을 입력받으며, 두번째줄 부터 M개의 숫자들이 N줄 나옴

5 4
10 5 9 5
4 1 1 7
7 5 1 6
3 4 8 6
3 4 3 6

===> 답: 34

풀이 코드

다익스트라를 이용한 풀이 코드입니다. 위 예제를 이력하여 마지막에 나온 dist 배열의 값은 

[10, 15, 24, 28]
[14, 15, 16, 23]
[21, 20, 17, 23]
[24, 24, 25, 29]
[27, 28, 28, 34]

입니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;

    static int n, m;
    static int[][] MAP; 
    // Node 생성
    static class Node implements Comparable <Node> {
        int y;
        int x;
        int cost;
        Node(int y, int x, int cost) {
            this.y= y;
            this.x=x;
            this.cost=cost;
        }
        @Override
        public int compareTo(Node next) {
            if(cost < next.cost)
                return -1;
            if(cost > next.cost)
                return 1;
            return 0;
        }
    }

    static int[] ydir = {0, 0, 1, -1};
    static int[] xdir = {1, -1, 0, 0}; 

    static void dijkstra(int y, int x) {
        // 1. PQ 설정
        PriorityQueue<Node>pq = new PriorityQueue<>();
        // MAP[0][0] = 0, 0 위치로 진입하는 비용 
        pq.add(new Node(y, x, MAP[y][x]));

        // 2. dist 설정
        // dist[] = index : 노드번호 value : 최단거리 
        // dist[][] = [y][x] 좌표의 최단거리 
        int[][] dist = new int[n][m];
        // 초기화
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                dist[i][j] = Integer.MAX_VALUE;
            }
        }
        dist[y][x] = MAP[y][x]; 

        // dijkstra
        while(!pq.isEmpty()) {
            Node now = pq.poll();
            // 갈 수 있는 인접한 방향 체크 
            for(int i = 0; i < 4; i++) {
                int ny = now.y + ydir[i];
                int nx = now.x + xdir[i];
                // ** 필수체크 ** 범위체크 
                if(ny < 0 || nx < 0 || ny >= n || nx >= m)
                    continue;
                // 다음 노드까지의 비용
                // 지금 좌표까지 오기 위해 사용한 비용 + 다음 좌표로 진입하기 위한 비용
                int ncost = dist[now.y][now.x] + MAP[ny][nx];
                // 지금까지 기록된 [ny][nx]까지의 최소비용보다 같거나 크면 pass
                if(dist[ny][nx] <= ncost)
                    continue; 
                dist[ny][nx] = ncost;
                pq.add(new Node(ny, nx, ncost));
            }
        }
        System.out.println(dist[n-1][m-1]); // N-1,M-1 의 최단거리 출력
    }

    public static void main(String[] args) throws IOException {
        st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        // map init
        MAP = new int[n][m];
        // input
        for(int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < m; j++) {
                MAP[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        dijkstra(0, 0); //(0,0) 부터 시작
    }
}

 

다익스트라의 원리는 지난번 설명한 포스트에 있으니 참고하세요.

2021.06.14 - [Programe Note/Algorithm] - [Java] 다익스트라 알고리즘 - 최단경로

728x90
반응형
728x90
반응형

그래프 문제에서 대표적인 최단 경로를 구하는 알고리즘입니다. 인공위성 GPS 소프트웨어 등에서 가장 많이 사용된다고 알려져 있습니다. 하나의 정점에서 모든 정점으로 가는 최단 경로를 알려줍니다. (단, 음의 간선을 포함할 수 없음)

응용이 많은 부분이라 기본적인 내용을 확실히 숙지하여야 합니다.

 

동작과정

  1. 출발 노드를 설정
  2. 출발노드 기준으로 각 노드의 최소비용을 저장
  3. 방문하지 않은 노드 중에서 가장 비용이 적은 노드를 선택
  4. 해당 노드를 거쳐서 톡정한 노드로 가는 경우를 고려하여 최소 비용을 갱신
  5. 위 과정에서 3~4 과정을 반복

시간복잡도

  • 힙의 구조를 활용하면 : O(N * log N)

참고 사이트

 

데이크스트라 알고리즘 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 과학에서, 데이크스트라 알고리즘(영어: Dijkstra algorithm) 또는 다익스트라 알고리즘은 도로 교통망 같은 곳에서 나타날 수 있는 그래프에서 꼭짓점 간의

ko.wikipedia.org

 

기본코드

아래와 같은 그래프가 존재한다고 합시다. 0에서 시작하여 각 노드까지의 최단 거리를 구하는 코드입니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.PriorityQueue;

class Node implements Comparable<Node>{
    int n;
    int dist;

    Node(int a, int b) {
        n = a;
        dist = b;
    }

    @Override
    public int compareTo(Node tar) {
        if (tar.dist < this.dist) return 1; 
        if (tar.dist > this.dist) return -1; 
        return 0;
    }    

}

class 다익스크라_기본코드_단방향 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    static ArrayList<ArrayList<Node>> alist = new ArrayList<ArrayList<Node>>();
    static PriorityQueue<Node> q = new PriorityQueue<Node>();

    static int[] best;
    static int[] used;

    public static void main(String[] args) throws IOException {        

        int n = 5;
        best = new int[n];
        used = new int[n];

        for (int i = 0; i<n; i++) {
            alist.add(new ArrayList<>());
        }

        alist.get(0).add(new Node(2, 70));
        alist.get(0).add(new Node(1, 10));
        alist.get(0).add(new Node(4, 170));        
        alist.get(1).add(new Node(2, 50));
        alist.get(1).add(new Node(3, 20));
        alist.get(2).add(new Node(4, 60));    
        alist.get(3).add(new Node(2, 15));

        //다익스트라 초기세팅
        q.add(new Node(0, 0));
        for (int i = 0; i<n; i++) best[i] = Integer.MAX_VALUE;
        best[0] = 0;

        while(!q.isEmpty()) {
            Node via = q.poll();
            if (used[via.n] == 1) continue; //이미 했었던 경유지면 탈락
            if (best[via.n] != via.dist) continue; //예전정보면 탈락

            used[via.n] = 1;             

            for (int i = 0; i<alist.get(via.n).size(); i++) {
                Node tar = alist.get(via.n).get(i);

                //지금까지 구했던 최고의 비용보다, 더 저렴한 비용이 발견되면 
                if (best[tar.n] > via.dist + tar.dist) {
                    best[tar.n] = via.dist + tar.dist; //갱신 
                    q.add(new Node(tar.n, best[tar.n]));
                }
            }
        }

        System.out.println(best[4]);

        br.close();
        bw.close();
    }
}

0에서 시작하여 각 노드들의 최단 거리는 아래와 같이 빨강색 경로로 이동을하여 4까지 가는 최단경로의 거리는 105 입니다.

 

728x90
반응형

+ Recent posts