문제
- 문제 링크
BOJ 30466 - 우정은 BFS처럼, 사랑은 DFS처럼
$1$부터 $N$까지 번호가 메겨진 $N$개의 정점으로 이루어진 트리를 구하고자 한다.
$1$번 정점을 시작으로 $DFS$와 $BFS$를 수행할 때, $d_i$, $b_i$를 각각 $DFS$, $BFS$에서 $i$번 정점에 방문한 순서라고 정의하자.
이때, $\sum_{i=1}^{N}{|d_i-b_i|}$ 을 최대로 하는 트리를 만들어보자.
TL : $1$ sec, ML : $1024$ MB
$3 ≤ N ≤ 200,000$ 각 탐색에서, 순회 후보가 여럿인 경우에는 번호가 더 작은 정점을 먼저 방문한다.
알고리즘 분류
- 트리 (trees)
- 해 구성하기 (constructive)
풀이
적당한 $N$에 대해 이런 저런 트리 모양을 그려봤는데, 항상 식의 최댓값을 낼 것 같은 트리의 모양이 보였다.
$m = ⌊$$\frac{N}{2}⌋$ 라 하자.
간선을 {$1, 2$}, {$2, 3$}, ... , {$m, m+1$} 로, 즉 $m$개의 정점을 $1$번 정점으로부터 일렬로 이어준다.
나머지 $n - m - 1$개의 정점은, $1$번 정점을 둘러싼다.
이 경우, 계산해보면 알겠지만 $\sum_{i=1}^{N}{|d_i-b_i|}$ = $2*(m - 1) * (n - m - 1)$ 이고 이 값이 바로 최댓값이다.
전형적인 $Proof$ $By$ $AC$였는데, 엄밀한 증명은 어찌해야 할까?
전체 코드
1 2 3 4 5 6 7 8 9 10 11 | #include<bits/stdc++.h> int main() { int n; std::cin >> n; int m(n >> 1), i(1); std::cout << (long long)(m - 1) * (n * 2 - m * 2 - 2) << '\n'; for (; m--; i++) printf("%d %d\n", i, i + 1); for (i += 1; i <= n;) printf("1 %d\n", i++); } | cs |
comment
끝
'Problem Solving > Baekjoon Online Judge (Platinum)' 카테고리의 다른 글
백준 20933 - 마스크펑크 2077 (C++) (1) | 2023.11.11 |
---|---|
백준 24505 - blobhyperthink (C++) (6) | 2023.11.09 |
백준 23314 - Minimum Spanning Cactus (C++) (1) | 2023.10.09 |
백준 21025 - Healthy Lifestyle (C++) (1) | 2023.10.04 |
백준 26358, 26359 - A Prickly Problem – Black Edition (C++) (0) | 2023.10.03 |