📖 백준 1167번 : https://www.acmicpc.net/problem/1167

트리의 지름이란, 트리에서 임의의 두 점 사이의 거리 중 가장 긴 것을 말한다. 트리의 지름을 구하는 프로그램을 작성하시오.
트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2 ≤ V ≤ 100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. 정점 번호는 1부터 V까지 매겨져 있다.
먼저 정점 번호가 주어지고, 이어서 연결된 간선의 정보를 의미하는 정수가 두 개씩 주어지는데, 하나는 정점번호, 다른 하나는 그 정점까지의 거리이다. 예를 들어 네 번째 줄의 경우 정점 3은 정점 1과 거리가 2인 간선으로 연결되어 있고, 정점 4와는 거리가 3인 간선으로 연결되어 있는 것을 보여준다. 각 줄의 마지막에는 -1이 입력으로 주어진다. 주어지는 거리는 모두 10,000 이하의 자연수이다.
첫째 줄에 트리의 지름을 출력한다.
최장 거리를 구하는 방법을 고민하는데 시간을 많이 썼다. 정점이 10만개가 주어지기 때문에 내가 생각한 방법들로는 시간 내로 풀기 어려웠다. 결국 풀이를 찾아봤는데, 그래프의 최장거리를 구하는 방법이 꽤 재밌다.
트리 구조이기 때문에 사이클이 존재하지 않는 것이 보장된다. 그래프를 어떤 방법으로 탐색해도 상관없다. 나는 dfs를 활용해서 그래프 탐색을 했고 앞서 말한 로직으로 구현하니 풀렸다.
#include <iostream>
#include <vector>
using namespace std;
vector<pair<int, int>> graph[100001];
bool visited[100001];
int max_dist = 0;
int mNode;
void dfs(int node, int dist) {
if (dist > max_dist) {//maxDist일 때의 node를 저장
max_dist = dist;
mNode = node;
}
visited[node] = true;
for (int i = 0; i < graph[node].size(); i++) {
int x = graph[node][i].second;
int nxt_dist = graph[node][i].first;
if (!visited[x]) {
visited[x] = true;
dfs(x, dist + nxt_dist);
}
}
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int a, b = 0, w;
int v;
cin >> v;
for (int i = 0; i < v; i++) {
cin >> a;
while (true) {
cin >> b;
if (b == -1) break;
cin >> w;
graph[a].push_back({ w,b });
graph[b].push_back({ w,a });
}
}
dfs(1, 0);// 임의의 한 점에서 탐색을 시작한다.
max_dist = 0;//한번 더 탐색할 거니까 초기화
fill_n(visited, v + 1, false);
dfs(mNode, 0);// 임의의 한 점에서 탐색해 찾은 mNode에서 다시 최장 거리를 찾는다.
cout << max_dist;// mNode에서 찾은 최장 거리가 답.
return 0;
}