BOJ 12912 트리 수정
sorohue가 PS하는 블로그
BOJ 12912 트리 수정
문제 링크입니다.
지름 구하기
트리의 지름은 깊이 우선 탐색을 통해 구할 수 있습니다. 임의의 정점에서 가장 멀리 떨어진 정점이 트리의 지름의 양 끝 정점 중 하나임을 이용합니다.
- 아무 정점이나 하나 골라 그 정점과 가장 멀리 떨어진 정점 하나를 DFS로 찾습니다.
- 앞에서 찾은 그 정점과 가장 멀리 떨어진 다른 정점 하나를 DFS로 찾습니다.
- 두 단계를 통해 찾은 두 정점이 트리의 지름의 양 끝 점입니다.
지름-지름 구하기
트리에서 간선 하나를 지우면 그래프는 두 개의 트리로 쪼개집니다. 우리는 두 트리를 다시 이어서 지름을 최대화해야 하고, 그렇다면 두 트리의 지름 사이를 잇는 간선을 추가하는 게 좋겠네요.
트리를 이루는 모든 간선에 대해, 그 간선을 지우고 남은 두 트리의 지름을 각각 구한 뒤 지웠던 간선의 가중치를 두 트리의 지름의 합과 더해 그중 최댓값을 고르면 됩니다.
코드
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
32
33
34
35
36
37
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
int u[2024], v[2024];
ll w[2024];
vector<pll> e[2024];
pll dfs(int now, int pre, int barrier){
ll node = now; ll w = 0;
for(auto [nxt, nw] : e[now]){
if(pre == nxt) continue;
if(barrier == nxt) continue;
auto [nnode, nnw] = dfs(nxt, now, barrier);
nnw += nw;
if(nnw > w){
w = nnw;
node = nnode;
}
}
return {node, w};
}
int main(){
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int n; cin >> n;
for(int i = 1; i < n; i++){
cin >> u[i] >> v[i] >> w[i];
e[u[i]].push_back({v[i], w[i]});
e[v[i]].push_back({u[i], w[i]});
}
ll ans = 0;
for(int i = 1; i < n; i++) ans = max(ans, w[i]+dfs(dfs(u[i], v[i], v[i]).first, v[i], v[i]).second+dfs(dfs(v[i], u[i], u[i]).first, u[i], u[i]).second);
cout << ans;
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.