레야몬
[C++] 3176번 도로 네트워크 - 자료 구조, 트리, 최소 공통 조상, 희소 배열 본문
#include <iostream>
#include <vector>
#include <string.h>
#include <algorithm>
#define FOR(i, k, N) for(int i=k; i<=N; i++)
#define Vr first
#define R second
using namespace std;
const int MAX_TR = 20;
const int MAX_N = 100001;
const int INF = 987654321;
int N, K;
int DT[MAX_N];
int PA[MAX_N][MAX_TR];
int min_R[MAX_N][MAX_TR], max_R[MAX_N][MAX_TR];
pair<int, int> res;
vector<pair<int, int>> Vertex[MAX_N];
void dfs(int Pa, int no, int Depth, int len)
{
DT[no] = Depth, PA[no][0] = Pa;
min_R[no][0] = max_R[no][0] = len;
FOR(i, 1, Vertex[no].size())
if(Vertex[no][i-1].Vr!=Pa)
dfs(no, Vertex[no][i-1].Vr, Depth+1, Vertex[no][i-1].R);
}
pair<int, int> dis(int a, int b)
{
int Min=INF, Max=0;
if(DT[a] != DT[b]) {
if(DT[a] < DT[b]) swap(a, b);
int dif = DT[a]-DT[b];
for(int i=0; dif>0; i++) {
if(dif%2) { //Bit 계산
Min = min(Min, min_R[a][i]);
Max = max(Max, max_R[a][i]);
a = PA[a][i];
}
dif = dif>>1;
}
}
if(a != b) {
for(int k=MAX_TR-1; k>=0; k--) {
if(PA[a][k] && PA[b][k] && PA[a][k]!=PA[b][k]) {
Min = min({Min, min_R[a][k], min_R[b][k]});
Max = max({Max, max_R[a][k], max_R[b][k]});
a = PA[a][k]; b=PA[b][k];
}
}
Min = min({Min, min_R[a][0], min_R[b][0]});
Max = max({Max, max_R[a][0], max_R[b][0]});
}
return {Min, Max};
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
FOR(i, 0, MAX_N-1) FOR(j, 0, MAX_TR) min_R[i][j]=INF;
cin >> N;
FOR(i, 1, N-1) {
int a, b, r;
cin >> a >> b >> r;
Vertex[a].push_back({b, r});
Vertex[b].push_back({a, r});
}
dfs(0, 1, 0, 0);
FOR(k, 1, MAX_TR-1) {
FOR(idx, 1, N) {
if(PA[idx][k-1]) {
PA[idx][k] = PA[ PA[idx][k-1] ][k-1];
min_R[idx][k] = min(min_R[PA[idx][k-1]][k-1], min_R[idx][k-1]);
max_R[idx][k] = max(max_R[PA[idx][k-1]][k-1], max_R[idx][k-1]);
}
}
}
cin >> K;
while(K--) {
int a, b; cin >> a >> b;
res = dis(a, b);
cout << res.Vr << ' ' << res.R << '\n';
}
return 0;
}
희소 배열이 처음 보는 알고리즘이라서 공부한다고 많이 힘들었다. 희소 배열 너무 어려워요...ㅜㅜ
아무리 봐도 이해되지가 않아서... 어쩔 수 없이, 다른 사람의 코드를 참고해서 코드를 작성했다. 물론 시간을 줄였다.
아 그리고 다른 사람 코드를 보던 중 굉장히 깔끔하게 쓰인 코드가 있어서 아래에 참조하였다.
<Sparse Table Algorithm 1>
https://hello-capo.netlify.app/algorithm-sparse-table/
🧩 [Algorithm] 희소 배열(Sparse Table) 알고리즘 | hello-capo!
희소 배열(Sparse Table) 배열 원소의 개수가 무조건 배열의 length 값보다 작은 배열 데이터가 저장되지 않은 경우가 더 많은 희소 행렬과 같이, 희소 배열은 배열의 원소 위치가 연속적이지 않은 배
hello-capo.netlify.app
<Sparse Table Algorithm 2>
https://tech-interview.tistory.com/175
[C++] 희소 테이블(Sparse Table)
희소 테이블(Sparse Table) 배열이 정적이어야 한다. 즉, 배열 내용이 수정되면 안 된다. 배열의 아이디어는 분할 정복과 비슷하지만 더 빠르다. 기본 원리 모든 정점의 간선이 1개인 유향 그래프가
tech-interview.tistory.com
<Sparse Table Algorithm 3>
[자료구조] Sparse Table (희소 배열)
개념 제일 쉽게 설명하는 글
jisungbin.medium.com
<참고한 코드>
https://everenew.tistory.com/96
[백준] No.3176 - 도로 네트워크 (C++, 최소 공통 조상)
문제 https://www.acmicpc.net/problem/3176 3176번: 도로 네트워크 첫째 줄에 N이 주어진다. (2 ≤ N ≤ 100,000) 다음 N-1개 줄에는 도로를 나타내는 세 정수 A, B, C가 주어진다. A와 B사이에 길이가 C인 도로..
everenew.tistory.com
<깔끔한 코드(풀어야 볼 수 있습니다)>
https://www.acmicpc.net/source/48942184
로그인
www.acmicpc.net
※현재 고등학교 등교중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고 있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 11266번 단절점 - 그래프 이론, 단절점과 단절선 (0) | 2022.10.13 |
---|---|
[C++] 6549번 히스토그램에서 가장 큰 직사각형 - 자료 구조, 세그먼트 트리, 분할 정복, 스택 (0) | 2022.10.12 |
[C++] 1007번 벡터 매칭 - 수학, 브루트포스 (0) | 2022.10.07 |
[C++] 1761번 정점들의 거리 - 트리, 최소 공통 조상, 희소 배열 (0) | 2022.10.06 |
[C++] 2533번 사회망 서비스(SNS) - 트리, DP (0) | 2022.10.06 |