| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- Strongly Connected Component
- Prisma
- Binary Lifting
- ccw 알고리즘
- LCA
- DP
- map
- 2-SAT
- 이분 탐색
- localstorage
- 최소 공통 조상
- 비트필드를 이용한 dp
- trie
- 벨만-포드
- 트라이
- MongoDB
- Express.js
- 자바스크립트
- 게임 서버 아키텍처
- 분리 집합
- R 그래프
- Github
- JavaScript
- SCC
- Spin Lock
- PROJECT
- 그래프 탐색
- Behavior Design Pattern
- 강한 연결 요소
- 비트마스킹
Archives
- Today
- Total
dh_0e
[PS] 도로 네트워크 / C++ (백준 3176번) 본문
LCA 2(백준 11438번)처럼 희소 배열을 이용한 최소 공통 조상(Binary Lifting) 알고리즘을 활용한 문제.
[PS] LCA 2 / C++ (백준 11438번)
희소 배열(Sparse Table)을 사용해 LCA를 O($logn$)만에 구해야한다. 일반적으로 희소 배열을 사용하면 O(n)이 걸리기 때문에 Binary Lifting 방식으로 공통 조상을 찾는 과정이 필요하다. 풀이 과정1. 우선 df
dh-0e.tistory.com
구현이 꽤 복잡하지만 설계를 잘 하고, LCA를 적절하게 구현하면 쉽게 풀 수 있다.
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<pair<int, int>> vec[100001];
int depth[100001], vi[100001];
pair<int, pair<int, int>> parent[100001][21];
void dfs(int node, int _depth) {
vi[node] = 1;
depth[node] = _depth;
int size = vec[node].size();
for (int i = 0; i < size; i++) {
int next_node = vec[node][i].first, cost = vec[node][i].second;
if (vi[next_node] == 0) {
parent[next_node][0].first = node;
parent[next_node][0].second.second=parent[next_node][0].second.first = cost;
dfs(next_node, _depth + 1);
}
}
return;
}
pair<int, int> LCA(int a, int b)
{
pair<int, int> pa = make_pair(1e9, 0);
if (depth[a] < depth[b])swap(a, b);
for (int i = 18; i >= 0; i--) {
if (depth[a] - depth[b] >= (1 << i)) {
pa.first = min(pa.first, parent[a][i].second.first);
pa.second = max(pa.second, parent[a][i].second.second);
a = parent[a][i].first;
}
}
if (a == b)return pa;
for (int i = 18; i >= 0; i--) {
if (parent[a][i].first != parent[b][i].first) {
pa.first = min(pa.first, min(parent[a][i].second.first, parent[b][i].second.first));
pa.second = max(pa.second, max(parent[a][i].second.second, parent[b][i].second.second));
a = parent[a][i].first;
b = parent[b][i].first;
}
}
pa.first = min(pa.first, min(parent[a][0].second.first, parent[b][0].second.first));
pa.second = max(pa.second, max(parent[a][0].second.second, parent[b][0].second.second));
return pa;
}
int main()
{
int n, m;
scanf("%d", &n);
for (int i = 1; i < n; i++) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
vec[a].push_back(make_pair(b, c));
vec[b].push_back(make_pair(a, c));
}
dfs(1, 0);
for (int i = 1; i <= 18; i++) {
for (int j = 1; j <= n; j++) {
pair<int, int> pa_1 = parent[j][i - 1].second;
pair<int, pair<int, int>>pa_2 = parent[parent[j][i - 1].first][i - 1];
pa_1.first = min(pa_1.first, pa_2.second.first);
pa_1.second = max(pa_1.second, pa_2.second.second);
parent[j][i] = make_pair(pa_2.first, pa_1);
}
}
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
int a, b;
scanf("%d %d", &a, &b);
pair<int, int> pa = LCA(a, b);
printf("%d %d\n", pa.first, pa.second);
}
return 0;
}'Problem Solving > Baekjoon' 카테고리의 다른 글
| [PS] Strongly Connected Component / C++ (백준 2150번) (3) | 2025.08.07 |
|---|---|
| [PS] 거의 최단 경로 / C++ (백준 5719번) (3) | 2025.08.04 |
| [PS] LCA 2 / C++ (백준 11438번) (1) | 2025.07.30 |
| [PS] 수열과 쿼리 16 / C++ (백준 14428번) (1) | 2025.07.29 |
| [PS] 교수님은 기다리지 않는다 / C++ (백준 3830번) (2) | 2025.07.28 |