Skip to content

Latest commit

 

History

History
534 lines (418 loc) · 14 KB

9회차_2022.07.06_특정한최단경로.md

File metadata and controls

534 lines (418 loc) · 14 KB

image

강지웅

func 특정한최단경로() {
    /**
     input start -----
     */
    var input: [Int] = readLine()!.split(separator: " ").map { Int($0)! }
    let N: Int = input[0] // node 갯수
    let E: Int = input[1] // edge 갯수
    
    /**
     그래프
     i 인덱스에는 (to, distance) 형태로 저장
     ex)
     graph[i][0].to 는 i에서의 목적지
     graph[i][0].cost 는 i에서 목적지까지의 거리
     */
    var graph: [[(to: Int, cost: Int)]] = [[(Int, Int)]](repeating: [], count: N + 1)
    
    for _ in 0..<E {
        input = readLine()!.split(separator: " ").map { Int($0)! }
        graph[input[0]].append((input[1], input[2]))
        graph[input[1]].append((input[0], input[2]))
    }
    
    input = readLine()!.split(separator: " ").map { Int($0)! }
    let v1: Int = input[0] // 경유 1
    let v2: Int = input[1] // 경유 2
    /**
     ----- input end
     */
    
    var routes: [Int] = []
    var distances: [[Int]] = [[Int]](repeating: [Int](repeating: 2_000_000_000, count: N + 1), count: N + 1)
    var isVisited: [[Bool]] = [[Bool]](repeating: [Bool](repeating: false, count: N + 1), count: N + 1)
    
    for i in 1...N {
        distances[i][i] = 0
    }
    
    getShortestDistance(from: 1)
    getShortestDistance(from: v1)
    getShortestDistance(from: v2)
    
    routes.append(distances[1][v1] + distances[v1][v2] + distances[v2][N])
    routes.append(distances[1][v2] + distances[v2][v1] + distances[v1][N])
    
    let result = routes.min()!
    
    print("\(result > 0 && result < 2_000_000_000 ? result : -1)")
    /**
     1. (1 -> v1) + (v1 -> v2) + (v2 -> N)
     2. (1 -> v2) + (v2 -> v1) + (v1 -> N)
     */
    
    func getShortestDistance(from: Int) {
        var now: Int
        
        while true {
            now = getMinIndex(from: from)
            
            if now == 0 {
                return
            }
            
            for connectedCity in graph[now] {
                if connectedCity.cost + distances[from][now] < distances[from][connectedCity.to] {
                    distances[from][connectedCity.to] = connectedCity.cost + distances[from][now]
                }
            }
        }
    }
    
    func getMinIndex(from: Int) -> Int {
        var min: Int = Int.max
        var minIndex: Int = 0
        
        for i in 1...N {
            if distances[from][i] < min && !isVisited[from][i] {
                minIndex = i
                min = distances[from][i]
            }
        }
        
        isVisited[from][minIndex] = true
        return minIndex
    }
}

김진산

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

//BOJ_1504_특정한 최단경로
class Main{

    public static final int INF = 987654321;

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        int N = Integer.parseInt(st.nextToken()); // 정점의 수
        int E = Integer.parseInt(st.nextToken()); // 간선의 수

        //간선 정보 리스트 배열 초기화
        List<Edge> edges[] = new List[N+1];
        for (int i = 1; i<=N; i++){
            edges[i] = new ArrayList<>();
        }

        //간선 정보 입력
        for (int i = 0; i<E; i++){
            st = new StringTokenizer(br.readLine(), " ");
            int from = Integer.parseInt(st.nextToken());
            int to = Integer.parseInt(st.nextToken());
            int cost = Integer.parseInt(st.nextToken());
            edges[from].add(new Edge(to, cost)); // 무방향 그래프
            edges[to].add(new Edge(from, cost));
        }

        //임의의 두 정점
        st = new StringTokenizer(br.readLine(), " ");
        int u = Integer.parseInt(st.nextToken());
        int v = Integer.parseInt(st.nextToken());

        System.out.println(findShortPath(u, v, N, edges));

        br.close();
    }

    //두 정점을 지나는 경로 찾기
    public static long findShortPath(int u, int v, int N, List<Edge> edges[]){
        long p1 = 0; //1 - u - v - N;
        long p2 = 0; //1 - v - n - N;

        p1 += dijkstra(1, u, N, edges);
        p1 += dijkstra(u, v, N, edges);
        p1 += dijkstra(v, N, N, edges);

        p2 += dijkstra(1, v, N, edges);
        p2 += dijkstra(v, u, N, edges);
        p2 += dijkstra(u, N, N, edges);

        long ans = Math.min(p1, p2);
        if (ans >= INF) return -1; //경로가 없는 경우
        return ans;
    }

    //from 에서 to 까지의 최단 거리
    public static long dijkstra(int from, int to, int N, List<Edge> edges[]){
        PriorityQueue<Edge> pq = new PriorityQueue<>();
        long[] distance = new long[N+1];
        Arrays.fill(distance, INF);
        distance[from] = 0;
        pq.offer(new Edge(from, distance[from]));

        while (!pq.isEmpty()){
            Edge now = pq.poll();

            if (now.to == to) return distance[to]; // 목적지 도달한 경우

            for (Edge e : edges[now.to]){
                if (distance[e.to] > distance[now.to] + e.cost){
                    distance[e.to] = distance[now.to] + e.cost;
                    pq.offer(new Edge(e.to, distance[e.to]));
                }
            }
        }

        return INF;
    }

    public static class Edge implements Comparable<Edge>{
        int to;
        long cost;
        public Edge(int to, long cost){
            this.to = to;
            this.cost = cost;
        }

        @Override
        public int compareTo(Edge o) {
            return Long.compare(this.cost, o.cost);
        }
    }
}

서예진

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class ShortPath {

    static final int INF = 9876543;
    static List<List<Node>> graph = new ArrayList<>();

    static int N, E;
    static int a, b, c;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        E = Integer.parseInt(st.nextToken());

        for(int i = 0; i < N + 1; i++){
            graph.add(new ArrayList<>());
        }

        for(int i = 0; i < E; i++){
            st = new StringTokenizer(br.readLine());
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());
            c = Integer.parseInt(st.nextToken());

            graph.get(a).add(new Node(b, c));
            graph.get(b).add(new Node(a, c));
        }

        st = new StringTokenizer(br.readLine());
        int waypoint1 = Integer.parseInt(st.nextToken());
        int waypoint2 = Integer.parseInt(st.nextToken());

        long distance1 = dijkstra(1, waypoint1) + dijkstra(waypoint1, waypoint2) + dijkstra(waypoint2, N);
        long distance2 = dijkstra(1, waypoint2) + dijkstra(waypoint2, waypoint1) + dijkstra(waypoint1, N);

        long min = Math.min(distance1, distance2);

        if(min >= INF){
            System.out.println("-1");
        }
        else {
            System.out.println(min);
        }

    }

    public static long dijkstra(int start, int end){
        PriorityQueue<Node> pq = new PriorityQueue<>();
        long[] result = new long[N + 1];
        boolean[] visited = new boolean[N + 1];

        Arrays.fill(result, INF);

        result[start] = 0;

        pq.offer(new Node(start, 0));

        while(!pq.isEmpty()){
            Node node = pq.poll();

            int idx = node.idx;
            long dis = node.distance;

            if(visited[idx]) {
                continue;
            }

            visited[idx] = true;

            for(Node n : graph.get(idx)) {
                if (dis + n.distance < result[n.idx]) {
                    result[n.idx] = dis + n.distance;

                    pq.offer(new Node(n.idx, result[n.idx]));
                }
            }
        }
        return result[end];
    }

}

class Node implements Comparable<Node>{
    int idx;
    long distance;

    Node(int idx, long distance){
        this.idx = idx;
        this.distance = distance;
    }

    @Override
    public int compareTo(Node o) {
        return Long.compare(this.distance, o.distance);
    }
}

오나연

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

public class Main_BOJ_1504_특정한최단경로_0704 {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		int max = 9876543;
		
		int N = Integer.parseInt(st.nextToken());
		int E = Integer.parseInt(st.nextToken());
		
		int[][] map = new int[N][N];
		int[] dist = new int[N];
		
		for(int i=0; i<N; i++) {
			for(int j=0; j<N; j++) {
				map[i][j] = max;
			}
		}
		
		for(int i=0; i<E; i++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken())-1;
			int b = Integer.parseInt(st.nextToken())-1;
			int c = Integer.parseInt(st.nextToken());
			
			map[a][b] = map[b][a] = c;
		}
		
		st = new StringTokenizer(br.readLine());
		int v1 = Integer.parseInt(st.nextToken())-1;
		int v2 = Integer.parseInt(st.nextToken())-1;
		
		// 1 -> v1 -> v2 -> N
		int way1 = dijkstra(0, v1, map, dist, max, N)
				+ dijkstra(v1, v2, map, dist, max, N) 
				+ dijkstra(v2, N-1, map, dist, max, N);
		
		// 1 -> v2 -> v1 -> N
		int way2 = dijkstra(0, v2, map, dist, max, N)
				+ dijkstra(v2, v1, map, dist, max, N) 
				+ dijkstra(v1, N-1, map, dist, max, N);
		
		int min = Math.min(way1, way2);

		
		if(min>=max) {
			System.out.println("-1");
		} else {
			System.out.println(min);
		}
	}
	
	static int dijkstra(int start, int end, int[][] map, int[] dist, int max, int N) {
		Arrays.fill(dist, max);
		dist[start] = 0;
		PriorityQueue<Node> pq = new PriorityQueue<>();
		pq.offer(new Node(start, dist[start]));
		
		while(!pq.isEmpty()) {
			Node cur = pq.poll();
			int idx = cur.idx;
			int cost = cur.cost;
			if(cost > dist[idx]) continue;
			for(int i=0; i<N; i++) {
				if(map[idx][i] == max) continue;
				if(dist[i] > dist[idx] + map[idx][i]) {
					dist[i] = dist[idx] + map[idx][i];
					pq.offer(new Node(i, dist[i]));
				}
			}
		}
		return dist[end];
	}
	
	static class Node implements Comparable<Node>{
		int idx;
		int cost;
		public Node(int idx, int cost) {
			this.idx = idx;
			this.cost = cost;
		}
		public int compareTo(Node o) {
			return this.cost - o.cost;
		}
	}
}

이주형

정윤영

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

public class BOJ_1504 {

    static int N, E;
    static int[][] map;
    static boolean flag;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        E = Integer.parseInt(st.nextToken());

        map = new int[N+1][N+1];

        for(int i=1; i<=N; i++){
            Arrays.fill(map[i], 987654321);
        }

        for(int i=0; i<E; i++){
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());
            int to = Integer.parseInt(st.nextToken());
            int dis = Integer.parseInt(st.nextToken());

            if(map[from][to] != 987654321){
                map[from][to] = Math.min(map[from][to], dis);
                map[to][from] = map[from][to];      //양방향
            }else{
                map[from][to] = dis;
                map[to][from] = dis;
            }
        }

        st = new StringTokenizer(br.readLine());
        int v1 = Integer.parseInt(st.nextToken());
        int v2 = Integer.parseInt(st.nextToken());

        //1번에서 N번으로 이동할떄 V1, V2 무조건 지나가기
        int distance = -1;

        //경우1 : 1 -> v1 -> v2 -> N
        int case1 = 0;
        flag = false;
        case1 += dijkstra(1, v1);
        case1 += dijkstra(v1, v2);
        case1 += dijkstra(v2, N);

        if(flag){
            case1 = 987654321;
        }

        //경우2 : 1 -> v2 -> v1 -> N
        int case2 = 0;
        flag = false;
        case2 += dijkstra(1, v2);
        case2 += dijkstra(v2, v1);
        case2 += dijkstra(v1, N);


        if(flag){
            case2 = 987654321;
        }

        //경우3: 갈 수 있는 경우 없음
        if(case1 != 987654321 || case2 != 987654321){
             distance = Math.min(case1, case2);
        }

        System.out.println(distance);
    }

    public static int dijkstra(int start, int finish){
        boolean[] visited = new boolean[N+1];
        int[] dis = new int[N+1];
        Arrays.fill(dis, 987654321);

        dis[start] = 0;

        for(int i=1; i<=N; i++){
            int min = Integer.MAX_VALUE;
            int current = 1;
            for(int j=1; j<=N; j++){
                if(!visited[j] && min > dis[j]){
                    min = dis[j];
                    current = j;
                }
            }

            visited[current] = true;

            for(int j=1; j<=N; j++){
                if(!visited[j] && map[current][j] != -1 && dis[j] > dis[current] + map[current][j]){
                    dis[j] = dis[current] + map[current][j];
                }
            }
        }
        if(dis[finish] == 987654321){
            flag = true;
        }
        return dis[finish];
    }
}

/*
2 0
1 2
*/