어흥
[백준 1167] 트리의 지름 (C++) 본문
문제 링크: https://www.acmicpc.net/problem/1167
1167번: 트리의 지름
트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2≤V≤100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. (정점 번호는 1부터 V까지 매겨져 있다고 생각한다) 먼저 정점 번호가 주어지고, 이어서 연결된 간선의 정보를 의미하는 정수가 두 개씩 주어지는데, 하나는 정점번호, 다른 하나는 그 정점까지의 거리이다. 예를 들어 네 번째 줄의 경우 정점 3은 정점 1과 거리가 2인 간선으로 연결되
www.acmicpc.net
1. 주의할 점
- 모든 Node에 대해 돌릴 경우 N^2 -> 시간초과 발생
- 시작 Node를 기준으로 Leaf 까지의 거리를 이용
2. 구현
- 트리의 지름이 되는 경우는 크게 2가지다
첫 번째로 트리가 1자 형태로 되어 있어서 시작점부터 Leaf Node까지의 거리다
두 번째로 시작점에서 여러 Node로 갈 수 있을 때(2개 이상의 Node), 시작점부터 각 Leaf까지의 Node의 거리를 구한다. 만약 LeafNode의 조상(시작 Node의 자손이라고 가정)이 다를 경우 이들 합의 최대를 구한다.
2가지 가정을 모두 만족시키면서 구할 수 있는 방법은 다음과 같다.
1) 시작점 -> 최대거리 가지는 Node
2) 최대거리 가지는 Node -> 각 Node까지의 거리 중 최대값
- 시작 Node를 1로 두고 다익스트라 알고리즘을 통해 최대거리를 가지는 Node를 구한다
- 위에서 구한 Node를 바탕으로 다익스트라 알고리즘을 통해 최대거리의 길이을 구한다.
#define MAX 987654321
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
struct info {
int idx, val;
};
info tmp;
vector<info> v[100001];
int dist[100001], result = 0, maxleaf = 0, maxi, node;
void dijkstra(int start) {
for (int i = 1; i <= node; i++)
dist[i] = MAX;
queue<info> q;
tmp.idx = start;
tmp.val = 0;
q.push(tmp);
dist[start] = 0;
maxi = 0;
while(!q.empty()) {
int cidx = q.front().idx;
int cv = q.front().val;
q.pop();
for (int i = 0; i < v[cidx].size(); i++) {
int next = v[cidx][i].idx;
int nv = v[cidx][i].val;
if (dist[next] > cv + nv) {
dist[next] = cv + nv;
tmp.idx = next;
tmp.val = cv + nv;
q.push(tmp);
if (cv + nv > maxi) {
maxi = cv + nv;
maxleaf = next;
}
}
}
}
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int n, start, val;
cin >> node;
for (int i = 1; i <= node; i++) {
cin >> n;
while (1) {
cin >> start;
if (start == -1) break;
cin >> val;
tmp.idx = start;
tmp.val = val;
v[n].push_back(tmp);
tmp.idx = n;
v[start].push_back(tmp);
}
}
dijkstra(1);
dijkstra(maxleaf);
cout << maxi;
system("pause");
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준 7348] 테이블 옮기기 (C++) (0) | 2020.03.18 |
---|---|
[백준 2079, 1509] 팰린드롬 / 팰린드롬 분할 (C++) (0) | 2020.03.17 |
[백준 14405] 피카츄 (C++) (0) | 2020.03.16 |
[백준 2151] 거울 설치 (C++) (0) | 2020.03.16 |
[백준 9207] 페그 솔리테어 (C++) (0) | 2020.03.15 |