기본 콘텐츠로 건너뛰기

백준알고리즘 1167번, 트리의 지름 풀이

트리의 지름은 두 vertex간의 길이가 가장 긴 값입니다. 
이 문제에서는 간선에 가중치가 있기 때문에 멀어도 길이가 짧은 수 있고 그 반대가 될 수도 있습니다.
트리의 지름을 구하는 방법은 

1. 임의의 정점으로 부터 가장 먼 정점을 구한다.
2. 1에서 나온 정점으로 부터 가장 먼 정점을 구한다.
3. 1과 2에서 나온 정점간의 거리가 트리의 지름!

이 방법은 공식처럼 외우시면 됩니다. 증명은 구글링 하시면 잘 나옵니다.

저는 큐를 이용해 BFS로 풀었습니다. BFS로 계속 풀어서 그런지 이게 편하네요.
임의의 정점을 1번노드로 잡아서 BFS를 한번 수행하고, 거기서 나온 정점으로 한번 더 수행해서 구했습니다.


-----------------------------------------------------------------------------------

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <functional>
#include <utility>

using namespace std;

typedef pair<int, int> P; //노드, 거리

int main(void) {
int V, u, v, w;
vector<P> adj[100001];
bool visited[100001] = { false };
int cost[100001] = { 0 };
queue<int> q;
int curr, next, weight, max_weight=0,max_node;

#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif

scanf("%d\n", &V);
for (int i = 0; i < V; i++) {
scanf("%d", &u);
do
{
scanf("%d", &v);
if (v != -1) {
scanf("%d", &w);
adj[u].push_back(P(v, w));
}

} while (v!=-1);
}

q.push(1); //1번 노드를 기준으로 BFS
while (!q.empty()) {
curr = q.front();
q.pop();
visited[curr] = true;
for (int i = 0; i < adj[curr].size(); i++) {
next = adj[curr][i].first;
if (visited[next] == false) {
weight = adj[curr][i].second;
cost[next] = cost[curr] + weight;
if (cost[next] > max_weight) {
max_weight = cost[next];
max_node = next;
}
q.push(next);
}
}
}

memset(visited, 0, sizeof visited);
memset(cost, 0, sizeof cost);

q.push(max_node); // 위의 BFS수행에서 나온 노드를 바탕으로 한번더 수행
while (!q.empty()) {
curr = q.front();
q.pop();
visited[curr] = true;
for (int i = 0; i < adj[curr].size(); i++) {
next = adj[curr][i].first;
if (visited[next] == false) {
weight = adj[curr][i].second;
cost[next] = cost[curr] + weight;
if (cost[next] > max_weight) {
max_weight = cost[next];
max_node = next;
}
q.push(next);
}
}
}

printf("%d\n", max_weight);


#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif

return 0;

}

댓글

이 블로그의 인기 게시물

맥스 어만(Max Ehrmann) - 소망(진정 바라는 것)

진정 바라는 것                                                                       -맥스 어만 소란스럽고 바쁜 일상속에서도  침묵 안에 평화가 있다는 사실을 기억하십시오 포기하지 말고 가능한한 모든 사람들과 잘 지내도록 하십시오 조용하면서도 분명하게 진실을 말하고  어리석고 무지한 사람들의 말에도 귀를 기울이십시오  그들 역시 할 이야기가 있을테니까요  목소리가 크고 공격적인 사람들은 피하십시오  그들은 영혼을 괴롭힙니다 자신을 다른 사람들과 비교하면 자신이 하찮아 보이고  비참한 마음이 들수도 있습니다  더 위대하거나 더 못한 사람들은 언제나...