BOJ 17532, ICPC Brazil Subregional 2019D Denouncing Mafia
๋ฌธ์ ๋งํฌ
๋์ด๋ : solved.ac ๊ธฐ์ค Platinum 4.
ํ์ด
๊ฒฐ๊ตญ ์ฃผ์ด์ง ๋ฌธ์ ๋, ์ด๋ค ํธ๋ฆฌ๊ฐ ์ฃผ์ด์ง ๋, ํธ๋ฆฌ์์ ์ต๋ $K$๊ฐ์ path๋ฅผ ํํ์ฌ ๊ทธ path๋ค์ union์ ์ต๋ํํ๋ ๋ฌธ์ ์ ๋๋ค.
๋ฌธ์ ์ ํน์ฑ ์, ํธ๋ฆฌ DP๋ฅผ ๋จผ์ ์๊ฐํด ๋ณผ ์ ์์ต๋๋ค.
dp[i][j]
: $i$๋ฒ์งธ ๋
ธ๋๋ฅผ ๋ฃจํธ๋ก ํ๋ subtree์ ๋ํด, $j$๊ฐ์ path๋ฅผ ํํ์ ๋์ ์ต๋๊ฐ
์ด DP๋ฅผ ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํด ๋ด
์๋ค. ๋ง์ฝ ๋ด child node์ ๋ํด ๋ชจ๋ dp๊ฐ์ ์๊ณ ์๋ค๋ฉด, ๋ด child node ๋ค์ ๋ํด ๊ฐ ๋
ธ๋๋น ๋ช๊ฐ์ chain์ ์ฌ์ฉํ ์ง๋ฅผ ์ ํด์ผ ํฉ๋๋ค. ์ด๋ ๊ตณ์ด ์ด์ฌํ ๋ณต์ก๋๋ฅผ ๊ณ์ฐํด ๋ณด์ง ์๋๋ผ๋, ์ ์ด๋ $O(NK)$ ์นธ์ DP๋ฅผ ๋ชจ๋ ์ฑ์์ผ ํ๊ธฐ ๋๋ฌธ์ ์ ํ ๋ต์ด ์์ต๋๋ค. ์๋ฅผ ๋ค์ด 3๊ฐ์ ์์๋
ธ๋๋ฅผ ๊ฐ์ง ๋
ธ๋์ ๋ํด dp[i][5]
๋ฅผ ๊ณ์ฐํ๋ ค๋ฉด, 5๋ฅผ 3๊ฐ๋ก ๋ถํ ํ๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ๋ํด ๊ฐ๊ฐ dp๊ฐ์ ๋ํด์ ํ์ธํด์ผ ํ๊ธฐ ๋๋ฌธ์ exponentialํ ์๊ฐ์ด ๊ฑธ๋ฆด ๊ฒ์
๋๋ค.
๋์ ํด์, ์ด๋ ๊ฒ ์๊ฐํด ๋ด ์๋ค. ์ดํ, ํ์ค๋ก ์ญ ์ฐ๊ฒฐ๋ path๋ฅผ ๊ฒฝ๋ก ๋๋ ์ฒด์ธ์ผ๋ก ํํํ๊ฒ ์ต๋๋ค.
- ๋ง์ฝ ์ต์ข ์ ์ธ ๋ต์ด, ํธ๋ฆฌ์์ ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก (๋ฃจํธ-๋ฆฌํ ์ค ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก)๋ฅผ ํฌํจํ์ง ์๋๋ค๋ฉด ์ ๋นํ ๊ฒฝ๋ก ํ๋๋ฅผ ๋นผ๊ณ ๋์ ์ ์ด ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก๋ฅผ ์ง์ด๋ฃ์ผ๋ฉด ๋ ์ข์ ๋ต์ด ๋ฉ๋๋ค.
- ์ด๋ฅผ ๊ท๋ฉ์ ์ผ๋ก ๋ฐ๋ณต ์ ์ฉํ๋ฉด, ๋ฌด์กฐ๊ฑด ํ์ฌ ๋จ์ ์๋ ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก๋ฅผ ํํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
- ๋จ, path์ ๊ธธ์ด์ ํฉ์ด ์๋๋ผ union์ ํฌํจ๋ ๋ ธ๋ ์๋ฅผ ์ธ๊ธฐ ๋๋ฌธ์, ์ด๋ฏธ ํ๋ฒ ๋ฐฉ๋ฌธ๋ ๋ ธ๋๋ ๋์ด์ path์ ๊ธธ์ด์ ์๋ฏธ๊ฐ ์์ต๋๋ค.
path์ ๊ฐ์๋ ๋๋ฌด ๋ง๊ณ , ์ฐ๋ฆฌ๋ ์ด์ฐจํผ ์ด๋ค ๋ ธ๋๋ฅผ ์ ํ๋ฉด ๊ฑฐ๊ธฐ์๋ถํฐ ๋ฆฌํ๊น์ง ๋ฌ๋ ค๊ฐ๋๊ฒ ์ต๋ํ ์ด๋์ด๊ธฐ ๋๋ฌธ์, โ์ด๋ค ๋ ธ๋๋ฅผ ๊ณจ๋ผ์โ ๊ทธ ๋ ธ๋๋ฅผ ๋ฃจํธ๋ก ํ๋ ์๋ธํธ๋ฆฌ์์ ๊ฐ์ฅ ๊น์ด ๋ค์ด๊ฐ ์๋ ๋ฆฌํ๊น์ง์ ๊ฒฝ๋ก๋ฅผ ํํ๋ค๊ณ ์๊ฐํด๋ ์ถฉ๋ถํฉ๋๋ค. ์ฆ, ํธ๋ฆฌ๋ฅผ ์๋ก disjointํ path๋ก ์๋ผ์ ์๊ฐํฉ๋๋ค.
์ด์ , ๋ฏธ๋ฆฌ ๋ชจ๋ path๋ฅผ priority queue์ ๋ฃ์ด๋๊ณ , ์ด๋ฅผ ๊ณ ๋ฅด๋ ์์ผ๋ก ๋๋ฆฝ๋๋ค. ๋จ, ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ ๋ค์ ๊ณ ๋ฅด์ง ์๋๋ก ์กฐ์ ํ๋ฉด ๋ฉ๋๋ค. ์๋ ๊ตฌํ์ด ์ถฉ๋ถํ ์ง๊ด์ ์ผ๋ก ์ฝํ๋ค๊ณ ์๊ฐํด์, ๋์ด์ ์ค๋ช ์ ์๋ตํ๊ฒ ์ต๋๋ค.
๊ตฌํ
#include <bits/stdc++.h>
#define usecppio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int N, K;
vector <int> T[101010];
int depth[101010];
bool vst[101010];
struct path {
int head;
int length;
int tail;
bool operator<(const path &o) const {
return length < o.length;
}
};
priority_queue<path> pq;
path dfs(int r, int p) {
depth[r] = depth[p] + 1;
path longest_path;
longest_path.length = 1;
longest_path.head = r;
longest_path.tail = r;
for (int c : T[r]) {
if (c == p) continue;
path child_path = dfs(c, r);
if (child_path.length + 1 > longest_path.length) {
longest_path.length = child_path.length + 1;
longest_path.tail = child_path.tail;
}
}
pq.push(longest_path);
return longest_path;
}
int parent[101010];
int32_t main() {
usecppio
cin >> N >> K;
for (int i = 2; i <= N; i++) {
int x; cin >> x;
T[i].push_back(x);
T[x].push_back(i);
parent[i] = x;
}
dfs(1, 0);
int ans = 0;
while (!pq.empty() and K) {
auto longest = pq.top();
pq.pop();
if (vst[longest.head]) continue;
ans += longest.length;
K -= 1;
for (int cur = longest.tail; cur != longest.head; cur = parent[cur]) {
vst[cur] = true;
}
vst[longest.head] = true;
}
cout << ans << '\n';
}