728x90
코드
import java.io.*;
import java.util.*;
public class Main {
static int n, m, k;
static int[] candy;
static ArrayList<Integer>[] graph;
static boolean[] visited;
static class Candy {
int kids;
int cnt;
public Candy(int kids, int cnt) {
this.kids = kids;
this.cnt = cnt;
}
}
static ArrayList<Candy> groupCandy = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int[] line = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
n = line[0]; m = line[1]; k = line[2];
candy = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
graph = new ArrayList[n];
for (int i = 0; i < n; i++) graph[i] = new ArrayList<>();
for (int i = 0; i < m; i++) {
line = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
graph[line[0] - 1].add(line[1] - 1);
graph[line[1] - 1].add(line[0] - 1);
}
visited = new boolean[n];
for (int i = 0; i < n; i++) {
if (!visited[i]) {
bfs(i);
}
}
int[] dp = new int[k];
int ans = 0;
for (Candy candy1 : groupCandy) {
for (int i = k - 1; i >= candy1.kids; i--) {
dp[i] = Math.max(dp[i], dp[i - candy1.kids] + candy1.cnt);
ans = Math.max(ans, dp[i]);
}
}
bw.write(Integer.toString(ans));
bw.flush();
}
private static void bfs(int target) {
LinkedList<Integer> queue = new LinkedList<>();
queue.add(target);
int kid = 0, candyCnt = 0;
while (!queue.isEmpty()) {
Integer poll = queue.poll();
if (!visited[poll]) {
visited[poll] = true;
kid++;
candyCnt += candy[poll];
for (Integer integer : graph[poll]) {
queue.add(integer);
}
}
}
groupCandy.add(new Candy(kid, candyCnt));
}
}
코드 설명
bfs + knapsack 문제이다.
초기 아이디어는 캔디가 많은 순으로 정렬한 후, 해당 그룹의 캔디를 뺏을 수 있다면 바로 뺏는 것이었다.
그래서 방문하지 않은 아이일 경우 bfs를 수행하는 것이었는데 이 경우는 '그룹 자체'의 캔디가 많은지 확인하지 않는다는 문제점이 있었다.
따라서, bfs는 캔디가 많은 순으로 수행하지만 bfs의 결과를 보았을 때 그 그룹이 가장 많은 캔디를 갖고 있는 것은 아닐 수도 있다는 것이다.
이 문제를 해결하기 위해 bfs로 그룹을 찾고 knapsack으로 최상의 답을 찾았다.
728x90
'코딩테스트 > 백준' 카테고리의 다른 글
P.10775 공항 (0) | 2023.09.27 |
---|---|
P.1766 문제집 (0) | 2023.09.25 |
P.16724 피리 부는 사나이 (0) | 2023.09.22 |
P.14003 가장 긴 증가하는 부분 수열 5 (0) | 2023.09.22 |
P.9328 열쇠 (1) | 2023.09.21 |