Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 포두부 보쌈
- 2020 KAKAO BLIND
- 동적 프로그래밍
- 양꼬치
- 문자열 압축
- dp
- 쓰레드 풀
- 알고리즘
- 2839
- 1로 만들기
- 프로그래머스
- HTTP API
- 투어
- 완도산회
- 맛집
- 2638
- 2589
- Spring
- Servlet
- 다이나믹 프로그래밍
- 백준
- 설탕 배달
- mvc
- 스프링 MVC
- 서블릿
- 고모네 콩탕
- 맛집 투어
- 스프링
- 호유동
- BFS
Archives
- Today
- Total
프로그래밍 공방
[백준] 3176번 : 도로 네트워크 본문
문제
3176번: 도로 네트워크
첫째 줄에 N이 주어진다. (2 ≤ N ≤ 100,000) 다음 N-1개 줄에는 도로를 나타내는 세 정수 A, B, C가 주어진다. A와 B사이에 길이가 C인 도로가 있다는 뜻이다. 도로의 길이는 1,000,000보다 작거나 같은 양
www.acmicpc.net
문제해결방법
이 문제는 최소 공통 조상(LCA)를 찾아서 푸는 문제였다.
2^i 번째 조상을 저장하는 배열로 만들면서 동일한 방법으로 2^i 까지의 경로에 있는 도로의 길이의 최대, 최소값을 저장하는 배열을 만든다.
두 도시가 주어지면 LCA를 찾으러 올라가면서 도로의 길이의 최대, 최소값을 찾으면서 올라간다.
코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | package baekjoon; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import java.util.Queue; import java.util.StringTokenizer; public class Main3176_도로네트워크 { public static int N, K; public static int[] depth; public static int[][] parent, maxValue, minValue; public static List<int[]>[] edge; public static void bfs(int root) { int d = 0; boolean[] v = new boolean[N+1]; Queue<Integer> q = new ArrayDeque<>(); q.add(root); v[root] = true; depth[root] = d++; maxValue[0][root] = Integer.MIN_VALUE; minValue[0][root] = Integer.MAX_VALUE; while(!q.isEmpty()) { int size = q.size(); for(int s=0; s<size; s++) { int cur = q.poll(); for(int[] e : edge[cur]) { if(!v[e[0]]) { v[e[0]] = true; depth[e[0]] = d; parent[0][e[0]] = cur; maxValue[0][e[0]] = e[1]; minValue[0][e[0]] = e[1]; q.add(e[0]); } } } d++; } } public static void makeParent() { for(int i=1; i<=20; i++) { for(int k=1; k<=N; k++) { parent[i][k] = parent[i-1][parent[i-1][k]]; if(parent[i-1][parent[i-1][k]]==0) continue; maxValue[i][k] = Math.max(maxValue[i-1][k], maxValue[i-1][parent[i-1][k]]); minValue[i][k] = Math.min(minValue[i-1][k], minValue[i-1][parent[i-1][k]]); } } } public static int[] lca(int l, int r) { int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; if(depth[l]>depth[r]) { int temp = l; l = r; r = temp; } for(int i=20; i>=0; i--) { if(depth[r]-depth[l] >= (1<<i)) { max = Math.max(max, maxValue[i][r]); min = Math.min(min, minValue[i][r]); r = parent[i][r]; } } if(r==l) return new int[] {min, max}; for(int i=20; i>=0; i--) { if(parent[i][l]!=parent[i][r]) { max = Math.max(max, maxValue[i][l]); max = Math.max(max, maxValue[i][r]); min = Math.min(min, minValue[i][l]); min = Math.min(min, minValue[i][r]); l = parent[i][l]; r = parent[i][r]; } } max = Math.max(max, maxValue[0][l]); max = Math.max(max, maxValue[0][r]); min = Math.min(min, minValue[0][l]); min = Math.min(min, minValue[0][r]); return new int[] {min, max}; } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; N = Integer.parseInt(br.readLine()); depth = new int[N+1]; parent = new int[21][N+1]; maxValue = new int[21][N+1]; minValue = new int[21][N+1]; edge = new List[N+1]; for(int i=1; i<=N; i++) edge[i] = new ArrayList<>(); for(int i=1; i<N; i++) { st = new StringTokenizer(br.readLine()); int a = Integer.parseInt(st.nextToken()); int b = Integer.parseInt(st.nextToken()); int c = Integer.parseInt(st.nextToken()); edge[a].add(new int[] {b, c}); edge[b].add(new int[] {a, c}); } bfs(1); makeParent(); int K = Integer.parseInt(br.readLine()); for(int i=0; i<K; i++) { st = new StringTokenizer(br.readLine()); int l = Integer.parseInt(st.nextToken()); int r = Integer.parseInt(st.nextToken()); int[] result = lca(l, r); System.out.println(result[0]+" "+result[1]); } } } | cs |
코드에 대한 피드백이나 더 좋은 아이디어는 언제나 환영입니다.
'개발 > 문제해결' 카테고리의 다른 글
[백준] 2042번 : 구간 합 구하기 (0) | 2020.12.07 |
---|---|
[프로그래머스] N으로 표현 (0) | 2020.12.07 |
[백준] 1915번 : 가장 큰 정사각형 (0) | 2020.11.27 |
[백준] 1504번 : 특정한 최단 경로 (0) | 2020.11.26 |
[프로그래머스] 구명보트 (0) | 2020.11.25 |