티스토리 뷰
문제
1693번: 트리 색칠하기
n개의 정점으로 이루어진 트리가 있다. 이 트리의 각 정점을 색칠하려고 한다. 색칠을 할 때에는 1, 2, 3, …, n번 색깔 중에 하나로 색칠하여야 한다. 각 색깔을 사용하여 한 개의 정점을 색칠할 때
www.acmicpc.net
풀이
트리DP를 사용합니다.
트리가 주어졌을 때 배열 \(dp\)를 다음과 같이 정의할 수 있습니다:
\(dp[i][j]:\) \(i\)의 색이 \(j\)일 때 \(i\)를 루트로 하는 서브트리의 총 비용의 최솟값.
여기서 \(j\)를 \(1\)부터 \(N\)까지 전부 다 구하면 \(N\)의 범위가 \(1\)이상 \(100000\)이하이기 때문에 시간초과가 날 수 있습니다.
www.acmicpc.net/board/view/13972의 글을 보니 최악의 경우 사용되는 색의 가짓수가 \(\log_{2} N\)임을 알 수 있었습니다.
트리를 순회하면서 \(dp[i][j]\)에 값을 저장해 나가면 쉽게 풀 수 있습니다.
시간복잡도: \(O(N \log N)\)
코드
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
int N, max_num;
vector<vector<int>> graph;
vector<vector<int>> dp;
void solve(int cur, int pnode) {
for (auto next : graph[cur]) {
if (next == pnode) continue;
solve(next, cur);
for (int i = 1; i <= max_num; ++i) {
int mn = 1e9;
for (int j = 1; j <= max_num; ++j)
if (i != j)
mn = min(mn, dp[next][j]);
dp[cur][i] += mn;
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N;
max_num = (int)floor(log2(N));
graph.resize(N + 1);
dp.resize(N + 1, vector<int>(max_num + 1));
for (int i = 0; i < N - 1; ++i) {
int a, b;
cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
for (int i = 0; i <= N; ++i)
for (int j = 1; j <= max_num; ++j)
dp[i][j] = j;
solve(1, 0);
int mn = 1e9;
for (int i = 1; i <= max_num; ++i)
mn = min(mn, dp[1][i]);
cout << mn << "\n";
return 0;
}'BOJ' 카테고리의 다른 글
| [BOJ 20506] Kaisar - 생존 (0) | 2021.05.15 |
|---|---|
| [BOJ 15669] 나무 위의 입자 (0) | 2021.05.13 |
| [BOJ 7812] 중앙트리 (0) | 2021.05.12 |
| [BOJ 1761] 정점들의 거리 (0) | 2021.05.12 |
| [BOJ 3584] 가장 가까운 공통 조상 (0) | 2021.05.08 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Coordinate Compression
- sorting
- 737-2
- Prefix Sum
- Greedy
- LCA
- DP Traceback
- Dijkstra
- DP
- Constructive
- hello
- Priority Queue
- Union Find
- Tree DP
- Combinatorics
- codeforces
- Sliding Window
- BOJ
- Tree
- binary search
- PBA
- Bit Masking
- graph
- knapsack
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
글 보관함