[백준] 1167번: 트리의 지름

2018. 5. 31. 02:24알고리즘

 

1167번: 트리의 지름

트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2≤V≤100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. (정점 번호는 1부터 V까지 매겨져 있다고 생각한다) 먼저 정점 번호가 주어지고, 이어서 연결된 간선의 정보를 의미하는 정수가 두 개씩 주어지는데, 하나는 정점번호, 다른 하나는 그 정점까지의 거리이다. 예를 들어 네 번째 줄의 경우 정점 3은 정점 1과 거리가 2인 간선으로 연결되

www.acmicpc.net

 

트리의 지름을 구하는 것은 생각보다 간단합니다.
트리의 특성상 양방향으로 연결된 노드들을 저장하게 되면, 어떤 노드든 루트 노드로 사용할 수 있습니다.
 
트리에서 일단 루트 노드에서 가장 멀리 떨어져 있는 노드를 찾고, 그 노드를 새로운 루트 노드로 삼습니다.
그 후, 새로운 루트에서 가장 멀리 떨어져 있는 노드를 찾고, 루트 노드와 가장 멀리 떨어져 있는 노드 사이의 거리를 구하면 이 거리가 트리의 지름이 됩니다.
가장 멀리 있는 노드를 찾을 때는 BFS 방식으로 탐색을 진행했습니다.
 
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct node{
  int num;
  int dist;

  node(int num, int dist) : num(num), dist(dist) {};
};

int V;
vector<vector<node> > tree;
vector<bool> isChecked;
vector<long long> distanceFromRoot;

void input() {
  cin >> V;
  tree.resize(V + 1);
  isChecked.resize(V + 1);
  distanceFromRoot.resize(V + 1);

  for (int i = 0; i < V; i++) {
    int vNum;
    cin >> vNum;

    int cvNum;
    int cvDist;
    while (cin >> cvNum && cvNum != -1) {
      cin >> cvDist;
      tree[vNum].push_back(node(cvNum, cvDist));
    }
  }
}

void initArray() {
  for (int i = 1; i <= V; i++) {
    isChecked[i] = false;
    distanceFromRoot[i] = -1;
  }
}

void bfs(int root) {
  initArray();

  queue<int> q;
  q.push(root);
  isChecked[root] = true;
  distanceFromRoot[root] = 0;

  while (!q.empty()) {
    int x = q.front();
    q.pop();

    for (node n : tree[x]) {
      int nx = n.num;
      int dist = n.dist;

      if (!isChecked[nx]) {
        isChecked[nx] = true;
        distanceFromRoot[nx] = distanceFromRoot[x] + dist;
        q.push(nx);
      }
    }
  }
}

int findNewRootNode(int root) {
  int newRoot = -1;
  long long dist = -1;
  bfs(root);

  for (int i = 1; i <= V; i++) {
    if (dist == -1 || dist < distanceFromRoot[i]) {
      dist = distanceFromRoot[i];
      newRoot = i;
    }
  }
  return newRoot;
}

void printAnswer(int farthestNode) {
  cout << distanceFromRoot[farthestNode] << '\n';
}

int main() {
  ios::sync_with_stdio(false);
  
  input();
  int newRoot = findNewRootNode(1);
  int farthestNode = findNewRootNode(newRoot);
  printAnswer(farthestNode);

  return 0;
}

'알고리즘' 카테고리의 다른 글

[백준] 1931번: 회의실 배정  (0) 2018.06.02
[백준] 11047번: 동전 0  (0) 2018.05.31
[백준] 1967번: 트리의 지름  (0) 2018.05.31
[백준] 11725번: 트리의 부모 찾기  (0) 2018.05.30
[백준] 9663번: N-Queen  (0) 2018.05.30