티스토리 뷰
문제
15681번: 트리와 쿼리
트리의 정점의 수 N과 루트의 번호 R, 쿼리의 수 Q가 주어진다. (2 ≤ N ≤ 105, 1 ≤ R ≤ N, 1 ≤ Q ≤ 105) 이어 N-1줄에 걸쳐, U V의 형태로 트리에 속한 간선의 정보가 주어진다. (1 ≤ U, V ≤ N, U ≠ V)
www.acmicpc.net
풀이
트리DP를 사용합니다.
트리가 주어졌을 때, 배열 \(dp\)를 다음과 같이 정의할 수 있습니다:
\(dp[i]:\) \(i\)를 루트로 하는 서브트리에 속한 정점의 수.
트리를 순회하면서 \(i\)의 자식 노드들을 \(c_{1}, c_{2}, c_{3}, ... , c_{m}\)이라고 할 때, \(dp[i]\)에 다음 값을 저장합니다:
$$dp[i] = 1 + \sum_{j = 1}^{m} dp[c_{j}]$$
각 쿼리마다 \(U\)가 주어졌을 때 \(dp[U]\)를 출력하면 됩니다.
코드
#include <bits/stdc++.h>
using namespace std;
int N, R, Q;
vector<vector<int>> arr;
vector<int> dp;
int solve(int cur, int pnode) {
for (auto node : arr[cur])
if (node != pnode)
dp[cur] += solve(node, cur);
return dp[cur];
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N >> R >> Q;
arr.resize(N + 1);
dp.resize(N + 1, 1);
for (int i = 0; i < N - 1; ++i) {
int a, b;
cin >> a >> b;
arr[a].push_back(b);
arr[b].push_back(a);
}
solve(R, 0);
while (Q--) {
int query;
cin >> query;
cout << dp[query] << "\n";
}
return 0;
}
'BOJ' 카테고리의 다른 글
[BOJ 3584] 가장 가까운 공통 조상 (0) | 2021.05.08 |
---|---|
[BOJ 1949] 우수 마을 (0) | 2021.05.05 |
[BOJ 11438] LCA 2 (0) | 2021.05.04 |
[BOJ 10942] 팰린드롬? (0) | 2021.05.03 |
[BOJ 11054] 가장 긴 바이토닉 부분 수열 (0) | 2021.05.03 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- hello
- Union Find
- codeforces
- Prefix Sum
- 737-2
- DP
- Tree DP
- PBA
- knapsack
- Priority Queue
- LCA
- graph
- binary search
- Greedy
- Bit Masking
- Tree
- Constructive
- Dijkstra
- Coordinate Compression
- DP Traceback
- Combinatorics
- Sliding Window
- sorting
- BOJ
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함