문제링크 : https://www.acmicpc.net/problem/1967
1967번: 트리의 지름
파일의 첫 번째 줄은 노드의 개수 n(1 ≤ n ≤ 10,000)이다. 둘째 줄부터 n-1개의 줄에 각 간선에 대한 정보가 들어온다. 간선에 대한 정보는 세 개의 정수로 이루어져 있다. 첫 번째 정수는 간선이 연
www.acmicpc.net
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAX = 987654321;
vector<pii>vec[100001];
bool visited[100001];
int result, target;
void dfs(int idx, int dist)
{
visited[idx] = 1;
if(result < dist)
{
result = dist; //가장 먼 거리 저장
target = idx; //가장 먼 지점 저장
}
for(int i=0; i<vec[idx].size(); i++)
{
auto[next, ncost] = vec[idx][i];
if(visited[next]) continue;
dfs(next, ncost + dist);
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int N;
cin >> N;
for(int i=0; i<N-1; i++)
{
int u, v, cost; //부모, 자식, 가중치
cin >> u >> v >> cost;
vec[u].push_back({v, cost});
vec[v].push_back({u, cost});
}
dfs(1, 0); //가장 먼 위치 구하기
memset(visited, 0, sizeof(visited)); //재탐색을 위해 초기화
dfs(target, 0); //가장 먼 위치에 대해 가장 먼 거리 구하기 (지름 구하기)
cout <<result;
return 0;
}
dfs 탐색을 2번 돌리는 문제이다.
처음에는 시작 점으로부터 가장 먼 위치를 먼저 구한다.
어느 위치에서 시작해도 상관없으며 이렇게 구한 가장 먼 위치가 양 쪽 지름 중의 하나가 된다.
그러고 나서 방금 구한 위치를 기준으로 다시 dfs를 돌려서 가장 먼 거리를 구한다.
당연하게도 지름의 양 끝이 서로 가장 멀기 때문에 이렇게 구한 값이 지름의 길이가 된다.
<예제>
위치 1에서 시작이라고 가정
가장 먼거리 위치 9 (2 + 11 + 15 = 28)
9에서 다시 탐색 시작
가장 먼거리 위치 12 (15 + 11 + 9 + 10 = 45)
다른 사람들의 풀이를 살펴보니 대부분 비슷하게 푼 것 같다.
근데 해당 문제가 N의 범위가 크지 않아서 모든 정점에 대해 전부 확인하는 방법인 N^2으로도 풀리는 것을 볼 수 있었다.
'백준 > 골드' 카테고리의 다른 글
[백준 2448번] 별 찍기 - 11 (C++) (0) | 2023.08.07 |
---|---|
[백준 1167번] 트리의 지름 (C++) (0) | 2023.08.05 |
[백준 16973번] 직사각형 탈출 (C++) (0) | 2023.07.29 |
[백준 2589번] 보물섬 (C++) (0) | 2023.07.27 |
[백준 28325번] 호숫가의 개미굴 (C++) (0) | 2023.07.26 |