문제: icpc.me/8872
문제의 내용을 풀어서 설명하면 결국 포레스트가 주어졌을 때 해당 포레스트에 몇개의 간선을 추가하여 만들어진 트리의 지름의 최솟값을 구하는 문제이다.
문제의 답은 세 경우중 하나가 될 수 있는데
1.기존의 포레스트내의 트리에서의 지름중 최댓값
2-3. 포레스트 내부의 서브트리들의 반지름 중 가장큰 반지름을 가지는 서브트리에 나머지 반지름들을 길이 L로 연결하였을 때
2.가장 긴 반지름 + 두번째로 긴 반지름 +L
3.두번째로 긴 반지름 + 세번째로 긴 반지름 +L+L
이 세값 중 최댓값이 답이된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include <cstdio> #include <algorithm> #include <vector> #include <cstring> #define INF 987654321 using namespace std; int n, m, k, x, y, z, u, v, r, g, res; vector<int> dist, back, ra, visited, visited2; vector<pair<int, int>> f; vector<vector<pair<int, int>>> vt; void dfs(int here, int dis) { visited[here] = 1; dist[here] = dis; if (dist[here] > r) { r = dist[here]; v = here; } for (auto next : vt[here]) { if (visited[next.first])continue; dfs(next.first, dis + next.second); } } void dfs2(int here, int dis) { visited2[here] = 1; dist[here] = dis; if (dist[here] > r) { r = dist[here]; u = here; } for (auto next : vt[here]) { if (visited2[next.first])continue; dfs2(next.first, dis + next.second); back[next.first] = here; } } int main() { scanf("%d%d%d", &n, &m, &k); vt.resize(n + 1); for (int i = 0; i < m; i++) { scanf("%d%d%d", &x, &y, &z); vt[x + 1].push_back({ y + 1,z }); vt[y + 1].push_back({ x + 1,z }); } back.assign(n + 1, 0); dist.assign(n + 1, INF); visited.assign(n + 1, 0); visited2.assign(n + 1, 0); for (int i = 1; i <= n; i++) { if (visited[i])continue; r = 0; u = i; dfs(i, 0); r = 0; back[v] = 0; dfs2(v, 0); f.push_back({ u ,r }); res = max(r, res); } for (auto next : f) { int it = next.first; g = INF; while (it) { int rad = max(dist[it], next.second - dist[it]); g = min(g, rad); it = back[it]; } ra.push_back(g); } sort(ra.rbegin(), ra.rend()); if (ra.size() >= 2) res = max(res, ra[0] + ra[1] + k); if (ra.size() >= 3) res = max(res, ra[1] + ra[2] + 2 * k); printf("%d\n", res); return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)2261 가장 가까운 두 점 (1) | 2017.07.09 |
---|---|
BOJ)5038 Flight Planning (0) | 2017.07.09 |
BOJ)1444 숌 언어 (0) | 2017.07.05 |
BOJ)9023 연습시즌 (0) | 2017.06.22 |
BOJ)13309 트리 (1) | 2017.06.21 |