[BOJ] 1238. 파티

Floyd-Warshall

  • 메모리 : 19,960 KB
  • 시간 : 1,452 ms
  • 코드길이 : 1,420 B
  • 소요시간 : 20M
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main_B_1238_파티 {

	static int INF = Integer.MAX_VALUE;
	static int N, M, X;
	static int[][] road;

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(in.readLine(), " ");
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		X = Integer.parseInt(st.nextToken());
		road = new int[N][N];

		for (int i = 0; i < N; i++) {
			Arrays.fill(road[i], INF);
		}

		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(in.readLine(), " ");
			road[Integer.parseInt(st.nextToken()) - 1][Integer.parseInt(st.nextToken()) - 1] = Integer.parseInt(st.nextToken());
		} // end input

		// 플로이드 워셜
		for (int k = 0; k < N; k++) {
			for (int i = 0; i < N; i++) {
				if (k == i) continue;
				for (int j = 0; j < N; j++) {
					if (k == j || i == j) continue;
					if (road[i][k] != INF && road[k][j] != INF && road[i][j] > road[i][k] + road[k][j]) {
						road[i][j] = road[i][k] + road[k][j];
					}
				}
			}
		}

		int max = Integer.MIN_VALUE;
		for (int i = 0; i < N; i++) {
			int sum = road[i][X - 1] + road[X - 1][i];
			max = Math.max(max, sum);
		}

		System.out.println(max);

	} // end main

}

Dijkstra

  • 메모리 : 72,176 KB
  • 시간 : 476 ms
  • 코드길이 : 2,332 B
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_B_1238_파티_dijkstra {

	static int N, M, X;
	static Node[] adjList; // 인접리스트

	static class Node {
		int no, weight;
		Node next;

		public Node(int no, int weight, Node next) {
			this.no = no;
			this.weight = weight;
			this.next = next;
		}
	}

	static class Point implements Comparable<Point> {
		int v, time;

		public Point(int v, int time) {
			this.v = v;
			this.time = time;
		}

		@Override
		public int compareTo(Point o) {
			return this.time - o.time;
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(in.readLine(), " ");
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		X = Integer.parseInt(st.nextToken()) - 1;
		adjList = new Node[N];

		int x, y, t;
		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(in.readLine(), " ");
			x = Integer.parseInt(st.nextToken()) - 1;
			y = Integer.parseInt(st.nextToken()) - 1;
			t = Integer.parseInt(st.nextToken());
			adjList[x] = new Node(y, t, adjList[x]);
		}

		int max = 0, temp = 0;
		for (int i = 0; i < N; i++) {
			if (i == X) continue;
			// i 가는 마을 파티하러 갈때
			temp = go(i, X);
			temp += go(X, i);
			if (max < temp)
				max = temp;
		}

		System.out.println(max);
	}

	// 다익스트라
	private static int go(int start, int end) {
		int[] D = new int[N];
		Arrays.fill(D, Integer.MAX_VALUE);
		boolean[] visited = new boolean[N];
		D[start] = 0;

		PriorityQueue<Point> queue = new PriorityQueue<Point>();
		queue.offer(new Point(start, 0));

		while (!queue.isEmpty()) {
			Point cur = queue.poll(); // 최소거리 정점 선택
			if (visited[cur.v]) continue;
			visited[cur.v] = true;

			if (cur.v == end)
				return cur.time;
			// 현 정점을 경유지로 해서 다른 정점들 비용 갱신
			for (Node temp = adjList[cur.v]; temp != null; temp = temp.next) {
				if (!visited[temp.no] && D[temp.no] > cur.time + temp.weight) {
					D[temp.no] = cur.time + temp.weight;
					queue.offer(new Point(temp.no, D[temp.no]));
				}
			}
		}

		return 0;
	}

}

Dijkstra_개선

  • 메모리 : 18,128 KB
  • 시간 : 148 ms
  • 코드길이 : 2,525 B
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_B_1238_파티_dijkstra_개선 {

	static int N, M, X;
	static Node[] adjList, radjList; // 인접리스트, 역간선 리스트

	static class Node {
		int no, weight;
		Node next;

		public Node(int no, int weight, Node next) {
			this.no = no;
			this.weight = weight;
			this.next = next;
		}
	}

	static class Point implements Comparable<Point> {
		int v, time;

		public Point(int v, int time) {
			this.v = v;
			this.time = time;
		}

		@Override
		public int compareTo(Point o) {
			return this.time - o.time;
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(in.readLine(), " ");
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		X = Integer.parseInt(st.nextToken()) - 1;
		adjList = new Node[N];
		radjList = new Node[N];

		int x, y, t;
		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(in.readLine(), " ");
			x = Integer.parseInt(st.nextToken()) - 1;
			y = Integer.parseInt(st.nextToken()) - 1;
			t = Integer.parseInt(st.nextToken());
			adjList[x] = new Node(y, t, adjList[x]); // x -> y로 가는 정보
			radjList[y] = new Node(x, t, radjList[y]); // y <- x 정보 (y는 x에서 온다.)
		}

		int max = 0, temp = 0;
		int[] gD = go(X, radjList); // 파티하러 갈 때
		int[] cD = go(X, adjList); // 파티에서 올 때

		for (int i = 0; i < N; i++) {
			if (i == X)
				continue;
			temp = gD[i] + cD[i];
			if (max < temp)
				max = temp;
		}
		System.out.println(max);
	}

	// 다익스트라
	private static int[] go(int start, Node[] adjList) {
		int[] D = new int[N];
		Arrays.fill(D, Integer.MAX_VALUE);
		boolean[] visited = new boolean[N];
		D[start] = 0;
		PriorityQueue<Point> queue = new PriorityQueue<Point>();
		queue.offer(new Point(start, 0));

		while (!queue.isEmpty()) {
			Point cur = queue.poll(); // 최소거리 정점 선택
			if (visited[cur.v])
				continue;
			visited[cur.v] = true;

			// 현 정점을 경유지로 해서 다른 정점들 비용 갱신
			for (Node temp = adjList[cur.v]; temp != null; temp = temp.next) {
				if (!visited[temp.no] && D[temp.no] > cur.time + temp.weight) {
					D[temp.no] = cur.time + temp.weight;
					queue.offer(new Point(temp.no, D[temp.no]));
				}
			}
		}

		return D;
	}

}

Leave a comment