https://www.acmicpc.net/problem/30206
30206번: 차량 배치
첫 번째 줄에 지점의 개수 $N$과 도로의 개수 $M$이 공백으로 구분되어 정수로 주어진다. $(1 \le N \le 200\,000;$ $N-1 \le M \le \min(\frac{N(N-1)}{2}, 200\,000))$ 이후 $M$개의 줄에 걸쳐 각 도로가 잇는 서로 다른
www.acmicpc.net
경우의 수 구하기
조건과 설명만 읽고 복잡해보일 수 있지만, 사실 뜯어보면 간단하기 그지없는 문제이다. 모든 연결은 가중치 1을 갖기 때문에 BFS로 1번 도로와의 거리를 구할 수 있다. 1번 도로까지의 거리를 깊이 라고 하자. 어떤 도로에서도 충돌이 일어나면 안되기 때문에, 깊이가 같은 도로가 두 개 이상이라면 한 번에 그 중 하나에만 차량을 배치해야 한다.
각 깊이에 해당하는 도로의 개수를 모두 셌다면, 그 다음에는 경우의 수를 구해야 한다. 각 깊이에는 도로의 개수 + 1개의 경우의 수가 있다. 각 도로를 선택하는 경우 + 아무 것도 선택하지 않는 경우 가 있기 때문이다. 따라서 모든 깊이를 순회하며 (도로의 개수 + 1)을 total에 곱해준다.
단, 이렇게 계산하는 경우 어떤 도로에도 차량을 배치하지 않는 경우, 즉 배치된 차량이 0개인 경우가 생긴다. 조건에서 최소 한 대의 차량이 배치되어야 한다고 했으므로 total - 1을 해주어야 한다. 만일 공교롭게도 total이 0이었을 수도 있기 때문에, 1을 빼준 후 total이 음수가 된다면 1000000007을 한 번 더해주도록 한다.
전체 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
List<Integer>[] list = new ArrayList[N];
int[] cnt = new int[N];
boolean[] v = new boolean[N];
for (int i = 0; i < N; i++) {
list[i] = new ArrayList<>();
cnt[i] = 1;
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int start = Integer.parseInt(st.nextToken()) - 1;
int end = Integer.parseInt(st.nextToken()) - 1;
list[start].add(end);
list[end].add(start);
}
Queue<int[]> que = new LinkedList<>();
que.offer(new int[] {0, 0});
v[0] = true;
while(!que.isEmpty()) {
int[] cur = que.poll();
cnt[cur[1]]++;
for (int i : list[cur[0]]) {
if(v[i]) continue;
v[i] = true;
que.offer(new int[] {i, cur[1] + 1});
}
}
long total = 1l;
for (int i = 0; i < N; i++) {
total *= cnt[i];
total %= 1000000007;
}
if(--total < 0) total += 1000000007;
System.out.println(total);
}
}
'JAVA > 문제 풀이' 카테고리의 다른 글
[백준 / BOJ] 1300번 : K번째 수 - JAVA (0) | 2023.10.29 |
---|---|
[백준 / BOJ] 17069번 : 파이프 옮기기 2 - JAVA (1) | 2023.10.15 |
[백준 / BOJ] 11053번 : 가장 긴 증가하는 부분 수열 - JAVA (1) | 2023.10.10 |
[백준 / BOJ] 30205번 : 전역 임무 - JAVA (0) | 2023.10.09 |
[백준 / BOJ] 10942번 : 팰린드롬? - JAVA (0) | 2023.10.09 |