본문 바로가기
Problem Solving/백준

백준 1939 : 중량제한

by Libi 2021. 7. 25.
반응형

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

 

1939번: 중량제한

첫째 줄에 N, M(1 ≤ M ≤ 100,000)이 주어진다. 다음 M개의 줄에는 다리에 대한 정보를 나타내는 세 정수 A, B(1 ≤ A, B ≤ N), C(1 ≤ C ≤ 1,000,000,000)가 주어진다. 이는 A번 섬과 B번 섬 사이에 중량제한이

www.acmicpc.net

[ 문제풀이 ]

처음에는 BFS + DP로 풀려고 했는데 설계를 잘못했는지 자꾸 틀렸습니다가 나왔다.

C의 범위가 굉장히 크고 최댓값을 구하는 최적화 문제이기 때문에 결정 문제로 변형할 수 있다. 따라서 파라메트릭 서치를 통해 해결하였다.

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.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	static class Edge {
		int to, cost;

		public Edge(int to, int cost) {
			this.to = to;
			this.cost = cost;
		}
	}

	static int N, M, S, E;
	static boolean[] visit;
	static List<Edge>[] edges;
	static Queue<Integer> q;

	public static void main(String[] args) throws IOException {
		try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			visit = new boolean[N + 1];
			edges = new ArrayList[N + 1];
			q = new LinkedList<>();
			for (int i = 0; i <= N; ++i) edges[i] = new ArrayList<>();
			for (int i = 0; i < M; ++i) {
				st = new StringTokenizer(br.readLine());
				int A = Integer.parseInt(st.nextToken());
				int B = Integer.parseInt(st.nextToken());
				int C = Integer.parseInt(st.nextToken());
				edges[A].add(new Edge(B, C));
				edges[B].add(new Edge(A, C));
			}

			st = new StringTokenizer(br.readLine());
			S = Integer.parseInt(st.nextToken());
			E = Integer.parseInt(st.nextToken());

			int left = 1, right = (int)1e9;
			int ans = 0;
			while (left <= right) {
				int mid = (left + right) >> 1;
				if (bfs(mid)) {
					ans = mid;
					left = mid + 1;
				} else {
					right = mid - 1;
				}
				
				Arrays.fill(visit, false);
				q.clear();
			}

			bw.write(ans + "\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static boolean bfs(int C) {
		q.offer(S);
		visit[S] = true;
		while (!q.isEmpty()) {
			int v = q.poll();
			
			if (v == E) return true;
			
			for (Edge e : edges[v]) {
				if (visit[e.to] || e.cost < C) continue;
				visit[e.to] = true;
				q.offer(e.to);
			}
		}
		return false;
	}
}
반응형

'Problem Solving > 백준' 카테고리의 다른 글

백준 2169 : 로봇 조종하기  (0) 2021.07.27
백준 2613 : 숫자구슬  (0) 2021.07.26
백준 20040 : 사이클 게임  (0) 2021.07.20
백준 11812 : K진 트리  (0) 2021.07.19
백준 3980 : 선발 명단  (0) 2021.07.17

댓글