Skip to main content

Rerooting

BOJ 30690 ์„ ๋กœ ์กฐ๋ฆฝ

·340 words·2 mins
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/30690 ๐Ÿง ๊ด€์ฐฐ ๋ฐ ์ ‘๊ทผ # ์•”ํŠผ ํŠธ๋ฆฌ๊ฐ€ ์žˆ๋‹ค ๊ฐ„์„  ํ•˜๋‚˜๋ฅผ ๋–ผ๊ณ  ๋‹ค์‹œ ์—ฐ๊ฒฐํ•ด์„œ, ๊ฐ€์žฅ ๋งŽ์€ ๊ฐ„์„ ์„ ์ง€๋‚˜๊ฐ€๊ณ ์‹ถ๋‹ค. ๊ฐ„์„  ํ•˜๋‚˜๋ฅผ ๋–ผ๊ณ  ๋‹ค์‹œ ์—ฐ๊ฒฐํ•ด์„œ, ํŠธ๋ฆฌ์˜ ์ง€๋ฆ„์„ ์ตœ๋Œ€๋กœ ํ•˜๊ณ  ์‹ถ๋‹ค. ์ชผ๊ฐœ์ง„ ๋‘๊ฐœ์˜ ํŠธ๋ฆฌ์—์„œ, ๊ฐ๊ฐ์˜ ์ง€๋ฆ„ + 1์ด ๋‹ต์ด๋‹ค. ํŠธ๋ฆฌ๋ฅผ ์“ฐ๋Š” ํŠธ๋ฆฌ ๋ฌธ์ œ ํ•ด๋‹น ๋ฌธ์ œ์—์„œ, ํ•ด๋‹น ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ์ œ์™ธํ•œ ํŠธ๋ฆฌ์˜ ์ง€๋ฆ„์„ ๊ตฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์ด๋Š” ๋ฆฌ๋ฃจํŒ…๊ณผ ๋ถ€๋ชจ๊นŠ์ด, ๋‹ค๋ฅธ ์ž์‹์˜ ๊นŠ์ด ๋‘๊ฐœ์ •๋„๋ฅผ ์ž˜ ๋“ค๊ณ ์žˆ์œผ๋ฉด ๊ฐ€๋Šฅํ•˜๊ฒ ๋‹ค. ๋‹ค๋ฅธ ์ž์‹์˜ ์ง€๋ฆ„๋„ ๋“ค๊ณ ์žˆ์–ด์•ผ ํ•œ๋‹ค!! ์˜ˆ์ œ ํŠธ๋ฆฌ ๊ทธ๋ฆผ ![[Drawing 2026-01-26 17.35.39.excalidraw.png]] ๐Ÿ’ป ํ’€์ด # ์ฝ”๋“œ (C++): int N, Q; vector<int> links[200010]; int depth[200010]; vector<pii> childs[200010]; // {mxDepth, nodeIdx} vector<pii> childs2[200010]; // {mxDiam, nodeIdx} int diam[200010], upDepth[200010], upDiam[200010]; void dfs1(int cur, int par){ vector<pii> ret; ret.push_back({0, cur}); for(auto nxt: links[cur]){ if(nxt == par) continue; depth[nxt] = depth[cur] + 1; dfs1(nxt, cur); diam[cur] = max(diam[cur], diam[nxt]); ret.push_back({childs[nxt][0].first + 1, nxt}); sort(all(ret), greater<pii>()); if((int)ret.size() > 3) ret.pop_back(); childs2[cur].push_back({diam[nxt], nxt}); sort(all(childs2[cur]), greater<pii>()); if((int)childs2[cur].size() > 2) childs2[cur].pop_back(); } childs[cur] = ret; if((int)ret.size() >= 2) diam[cur] = max(diam[cur], ret[0].first + ret[1].first); if((int)ret.size() >= 1) diam[cur] = max(diam[cur], ret[0].first); } void dfs2(int cur, int par, int mxUp){ for(auto nxt: links[cur]){ if(nxt == par) continue; vector<int> candidates; candidates.push_back(mxUp); for(auto [d, idx]: childs[cur]) if(idx != nxt) candidates.push_back(d); sort(all(candidates), greater<int>()); if((int)candidates.size() >= 2) upDiam[nxt] = max(upDiam[nxt], candidates[0] + candidates[1]); if((int)candidates.size() >= 1) upDiam[nxt] = max(upDiam[nxt], candidates[0]); for(auto [d, idx]: childs2[cur]) if(idx != nxt) upDiam[nxt] = max(upDiam[nxt], d); upDiam[nxt] = max(upDiam[nxt], upDiam[cur]); dfs2(nxt, cur, candidates[0] + 1); } } void solve(){ cin >> N >> Q; rep(i, 0, N-1){ int u, v; cin >> u >> v; links[u].push_back(v); links[v].push_back(u); } dfs1(1, -1); dfs2(1, -1, 0); // rep(i, 1, N+1) cout << diam[i] << " "; cout << "\n"; // rep(i, 1, N+1) cout << upDiam[i] << " "; cout << "\n"; while(Q--){ int u, v; cin >> u >> v; if(depth[u] < depth[v]) swap(u, v); cout << diam[u] + upDiam[u] + 1 << "\n"; } } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ

BOJ 32144 ํŠธ๋ฆฌ๋ฅผ ์“ฐ๋Š” ํŠธ๋ฆฌ ๋ฌธ์ œ

·358 words·2 mins
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/32144 ๐Ÿง ๊ด€์ฐฐ ๋ฐ ์ ‘๊ทผ # ๋ฌธ์ œ์— ๋‚ด ์ด๋ฆ„์ด ๋‚˜์™€์„œ ๊ธฐ๋ถ„์ด ์ข‹๋‹ค. ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ํ•˜๋‚˜ ์žก์•„์„œ, ๊ทธ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ์™€ ๊ทธ ๋ถ€๋ชจ์™€์˜ ์—ฐ๊ฒฐ์„ ๋Š๊ณ  ์„œ๋ธŒํŠธ๋ฆฌ์˜ ์ž„์˜์˜ ์ •์ ๊ณผ ๋ฐฉ๊ธˆ ๋Š์€ ๋ถ€๋ชจ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์—ฐ์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ง๊ด€์ ์œผ๋กœ, ํ•ด๋‹น ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ธธ์ด์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ๊นŠ์ด์—์„œ ์ง€๋ฆ„์œผ๋กœ ๋ฐ”๋€œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. Tree DP๋ฅผ ์ด์šฉํ•œ ํŠธ๋ฆฌ์˜ ์ง€๋ฆ„ ๊ตฌํ•˜๊ธฐ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค. ![[Drawing 2026-01-25 10.09.49.excalidraw.png]] ์œ„์™€ ๊ฐ™์€ ๊ฒฝ์šฐ๊ฐ™์€๊ฒŒ ๋ฐœ์ƒํ•  ๊ฒƒ ๊ฐ™๋‹ค. ๋‘๋ฒˆ์งธ๋กœ ์ž‘์€ ํŠธ๋ฆฌ์˜ ์ง€๋ฆ„๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ธฐ์กด ์ง€๋ฆ„์˜ ์–‘ ๋ ์ ์ค‘ ํ•œ ์ ์€ ์œ ์ง€๋œ๋‹ค. …์ธ์ค„์•Œ์•˜๋Š”๋ฐ ์•ˆ๋œ๋‹ค. ![[Drawing 2026-01-25 11.07.01.excalidraw.png]] ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„œ๋ธŒ๋…ธ๋“œ ์•ˆ์— ๊ธฐ์กด ํŠธ๋ฆฌ์˜ ์ง€๋ฆ„์ด ๋‹ค ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค… ๊ฒฐ๊ตญ ๋ฌธ์ œ์—์„œ๋„ ๋งํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ฌธ์ œ๋ฅผ ๋ถ€๋ถ„ํŠธ๋ฆฌ์™€ ๊ทธ ๋‚˜๋จธ์ง€๋กœ ๋ณด๋ฉด, ๋ฆฌ๋ฃจํŒ…์ด ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์„๊นŒ? ๋ฆฌ๋ฃจํŒ…์„ ์ด์šฉํ•ด์„œ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜์ž. ์„œ๋ธŒํŠธ๋ฆฌ์˜ ์ง€๋ฆ„ ํ•ด๋‹น ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ๊นŠ์€ ๊นŠ์ด ๋‘๊ฐœ (๋ฆฌ๋ฃจํŒ…์šฉ) ํ•ด๋‹น ๋…ธ๋“œ์—์„œ ์œ„๋กœ ๊ฐ”์„๋•Œ, ๊ฐ€์žฅ ๊นŠ์€ ๊ธธ์ด ์ด๋Š” dfs๋ฅผ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๊ณ , ์‹œ๊ฐ„๋ณต์žก๋„๋Š” $O(N)$์ด๋‹ค. ๋””๋ฒ„๊น…์„ ์œ„ํ•œ ์˜ˆ์ œ 2๋ฒˆ ๊ทธ๋ฆผ ![[Drawing 2026-01-25 10.30.52.excalidraw.png]] ๐Ÿ’ป ํ’€์ด # ์ฝ”๋“œ (C++): int N; vector<int> links[300005]; vector<pii> max_depth[300005]; int diam[300005]; int updepth[300005], updiam[300005]; vector<pii> dfs(int cur, int par){ vector<pii> v; v.push_back({0, cur}); for(auto nxt: links[cur]){ if(nxt == par) continue; auto nv = dfs(nxt, cur); diam[cur] = max(diam[cur], diam[nxt]); v.push_back({nv[0].first + 1, nxt}); sort(all(v), greater<pii>()); while(v.size() > 2) v.pop_back(); } if(v.size() >= 2) diam[cur] = max(diam[cur], v[0].first + v[1].first); else diam[cur] = max(diam[cur], v[0].first); max_depth[cur] = v; // cout << "cur: " << cur << " diam: " << diam[cur] << " max_depth: "; // for(auto p: v) cout << "(" << p.first << "," << p.second << ") "; // cout << '\n'; return v; } void dfs2(int cur, int par){ for(auto nxt: links[cur]){ if(nxt == par) continue; updepth[nxt] = updepth[cur] + 1; if(max_depth[cur][0].second != nxt) updepth[nxt] = max(updepth[nxt], max_depth[cur][0].first + 1); else if(max_depth[cur].size() >= 2) updepth[nxt] = max(updepth[nxt], max_depth[cur][1].first + 1); dfs2(nxt, cur); } } void solve(){ cin >> N; rep(i, 2, N+1){ int p; cin >> p; links[p].push_back(i); links[i].push_back(p); } dfs(1, -1); dfs2(1, -1); rep(i, 2, N+1) cout << max(diam[1], updepth[i] + diam[i]) << "\n"; } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ