본문 바로가기

카테고리 없음

(복습 꼭) 다익스트라 32388

 

 

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

 

 

다익스트라 

 

문제를 보면 좌표에서 점들간 "최단거리"를 구하는 문제이다.

음수의 가중치가 없는 최단거리란 뭐다 ? 

"다익스트라" 다 !!! 

 

 

아래 코드를 여러 번 보면서 다익스트라를 마스터 해보쟈.

문제가 어려워도 알고리즘을 정확하게 알고 있으면 풀 수 있다. 

 

// 최단거리 -> 다익스트라 !! 

import java.io.*;
import java.util.*;

public class Main{
    static int a, b;
    static int n;
    static int[][] nxny;
    static ArrayList<Node>[] graph;
    
    public static void main(String[] arge)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        
        a = Integer.parseInt(st.nextToken()); // 도착 x좌표
        b = Integer.parseInt(st.nextToken()); // 도착 y좌표
        n = Integer.parseInt(br.readLine()); // 간판의 수
        nxny = new int[n+2][2];
        
        nxny[0][0] = 0;
        nxny[0][1] = 0;
        nxny[n+1][0] = a;
        nxny[n+1][1] = b;
        for(int i=1; i<=n; i++){
            st = new StringTokenizer(br.readLine());
            nxny[i][0] = Integer.parseInt(st.nextToken()); // 간판 x좌표 입력받기
            nxny[i][1] = Integer.parseInt(st.nextToken()); // 간판 y좌표 입력받기
        }
        
        graph = new ArrayList[n+2]; // 간판 갯수 + 시작, 도착 
        for(int i=0; i<n+2; i++){
            graph[i] = new ArrayList<>();
        }
        // 연결 정보 저장 
        for(int i=0; i<n+2; i++){
            for(int j=0; j<n+2; j++){
                if(i!=j){
                    if((i==0 || i==n+1) && (j==0 || j==n+1)){ // 간판 0
                        double d = Math.sqrt(Math.pow(nxny[i][0]-nxny[j][0], 2)
                                             +Math.pow(nxny[i][1]-nxny[j][1], 2));
                        graph[i].add(new Node(j, d));
                        graph[j].add(new Node(i, d));
                    } else if (i==0 || i==n+1 || j== 0 || j==n+1){ // 간판 1
                        double d = Math.max(0.0, Math.sqrt(Math.pow(nxny[i][0]-nxny[j][0], 2)
                                             +Math.pow(nxny[i][1]-nxny[j][1], 2))-1);
                        graph[i].add(new Node(j, d));
                        graph[j].add(new Node(i, d));
                    } else{ // 간판 2
                        double d = Math.max(0.0, Math.sqrt(Math.pow(nxny[i][0]-nxny[j][0], 2)
                                                           +Math.pow(nxny[i][1]-nxny[j][1], 2))-2);
                        graph[i].add(new Node(j, d));
                        graph[j].add(new Node(i, d));
                    }
                }
            }
        }
        dijkstra();
    }
    
    // 가중치가 있는 그래프를 담기 위한 별도의 클래스 구현 (가중치 : 거리)
    static class Node implements Comparable<Node>{
        int index;
        double dist;
        
        public Node(int i, double d){
            this.index = i;
            this.dist = d;
        }
        
        // 우선순위 큐 정렬 기준을 위해 compareTo 함수 구현
        @Override
        public int compareTo(Node n){
            return Double.compare(this.dist, n.dist);
        }
    }
    
    static void dijkstra(){
        boolean[] visited = new boolean[n+2];
        double[] distance = new double[n+2];
        Arrays.fill(distance, Double.POSITIVE_INFINITY); // [암기]
        distance[0] = 0; // 출발은 거리 0
        
        PriorityQueue<Node> pq = new PriorityQueue<>();
        pq.offer(new Node(0, 0));
        while(!pq.isEmpty()){
            Node now = pq.poll();
            
            if(visited[now.index]) continue;
            visited[now.index] = true;
            for(Node next : graph[now.index]){
                if(distance[next.index] > distance[now.index]+next.dist){
                    distance[next.index] = distance[now.index]+next.dist;
                    pq.offer(new Node(next.index, distance[next.index]));
                }
            }
        }
        System.out.printf("%.10f\n", distance[n+1]);
    }
}

 

 

취운 다익스트라 복습 

https://programmer-seungg0.tistory.com/159