🖇️ 문제 링크
💡 문제 분석
파라메트릭 서치로 검역소마다 limit개 이하의 치료제로 K개의 검역소를 운영할 수 있는지를 구합니다.
검역소 한 개로 운영할 수 없을 때, 큰 도시부터 하나씩 검역소를 추가합니다.
⌨️ 코드
import java.io.*;
import java.util.*;
public class Q13209 {
static int N, K, cnt;
static int[] people;
static List<Integer>[] adj;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tc = stoi(br.readLine());
while(tc-- > 0) {
StringTokenizer st = new StringTokenizer(br.readLine());
N = stoi(st.nextToken());
K = stoi(st.nextToken());
people = new int[N];
adj = new ArrayList[N + 1];
for(int i = 1 ; i<= N; i++)
adj[i] = new ArrayList<>();
st = new StringTokenizer(br.readLine());
for(int i = 0; i < N; i++)
people[i] = stoi(st.nextToken());
for(int i = 0; i < N - 1; i++) {
st = new StringTokenizer(br.readLine());
int u = stoi(st.nextToken());
int v = stoi(st.nextToken());
adj[u].add(v);
adj[v].add(u);
}
long lo = 0, hi = 0;
for(int i = 0; i < N; i++) {
lo = Math.max(lo, people[i]);
hi += people[i];
}
while(lo <= hi) {
long mid = (lo + hi) / 2;
cnt = 0;
dfs(1, 1, mid);
if(cnt <= K)
hi = mid - 1;
else
lo = mid + 1;
}
System.out.println(hi + 1);
}
}
public static long dfs(int cur, int prev, long limit) {
Queue<Long> pq = new PriorityQueue<>(Collections.reverseOrder());
long curPeople = people[cur - 1];
for(int child : adj[cur])
if(child != prev) {
long childPeople = dfs(child, cur, limit);
pq.add(childPeople);
curPeople += childPeople;
}
while(curPeople > limit && !pq.isEmpty()) {
curPeople -= pq.poll();
cnt++;
}
return curPeople;
}
public static int stoi(String s) {
return Integer.parseInt(s);
}
}
⏱️ 결과
Uploaded by Notion2Tistory v1.1.0