개인사
[G4] 백준 20924번 트리의 기둥과 가지 C++ 트리, DFS, 깊이 우선 탐색 본문
728x90

리뷰

https://www.acmicpc.net/problem/20924
쉽게 보고 접근했던 문제인데 생각보다 처리해줘야 할 것이 많았다.
전역 변수
- N : 배열의 최대 크기를 정의할 상수 변수
- n : 노드의 개수를 저장할 변수
- r : 루트 노드의 번호를 저장할 변수
- mn : 기가 노드 번호를 저장할 변수
- mpn : 기가 노드의 부모 노드 번호를 저장할 변수
- r_to_m : 루트부터 기가 노드까지의 거리를 저장할 변수
- mx_dist : 기가 노드로부터 리프 노드까지의 거리 최대값을 저장할 변수
- edges : 간선 정보를 저장할 pii타입 벡터 배열
함수
1. FindMiddleNodeAndDist
void FindMiddleNodeAndDist( int cn, int pn, int dist )
{
if (
edges[ cn ].size() >= 2 && cn == r ||
edges[ cn ].size() >= 3 ||
( edges[ cn ].size() == 1 && cn != r )
)
{
mn = cn;
mpn = pn;
r_to_m = dist;
return;
}
for ( const auto& [ nn, w ] : edges[ cn ] )
{
if ( nn == pn ) continue;
FindMiddleNodeAndDist( nn, cn, dist + w );
}
}
루트 노드로부터 기가 노드까지의 거리의 합과 기가 노드의 번호를 구하기 위한 함수
2. FindLongestDistToLeafNode
void FindLongestDistToLeafNode( int cn, int pn, int dist )
{
if ( edges[ cn ].size() == 1 && cn != mn )
{
mx_dist = max( mx_dist, dist );
return;
}
for ( const auto& [ nn, w ] : edges[ cn ] )
{
if ( nn == pn ) continue;
FindLongestDistToLeafNode( nn, cn, dist + w );
}
}
기가 노드로부터 리프 노드까지의 최대 길이를 구하기 위한 함수
문제풀이
- n, r값을 입력 받고, n-1개의 간선 정보를 입력 받아 edges배열을 초기화한다.
- FindMiddleNodeAndDist함수에 r, -1, 0을 전달하여 r_to_m와 mn, mpn을 초기화한다.
- FindLongestDistToLeafNode함수에 mn, mpn, 0을 전달하여 mx_dist을 초기화한다.
- r_to_m과 mx_dist를 공백을 기준으로 구분하여 출력한다.
트러블 슈팅
- 간선이 부모->자식 순으로 들어올 것이라 가정하고 단방향 간선을 추가해 주어 WA를 받았다.
- 루트 노드가 기가 노드인 경우를 체크해 주지 않아 WA를 받았다.
- 기가 노드를 정확히 식별하고, 변수 mpn을 전역으로 선언해 FindLongestDistToLeafNode함수의 최초 호출부에 인자로 넘겨주어 루트 노드로 다시 타고 올라가는 경우를 막아 AC를 받았다.
참고 사항
- 기가 노드는 루트 노드에서 순회를 시작했을 때, 처음으로 자식 노드가 2개 이상인 노드다.
- 단, 리프 노드가 단 1개인 경우 리프 노드가 동시에 기가 노드가 된다.
- 또한, 루트 노드가 동시에 기가 노드인 경우도 가능하다.
정답 코드
#include <iostream>
#include <vector>
using namespace std;
using pii = pair< int, uint16_t >;
const int N = 2e5 + 1;
int n, r, mn, mpn, r_to_m, mx_dist;
vector< pii > edges[ N ];
void FindMiddleNodeAndDist( int cn, int pn, int dist )
{
if (
edges[ cn ].size() >= 2 && cn == r ||
edges[ cn ].size() >= 3 ||
( edges[ cn ].size() == 1 && cn != r )
)
{
mn = cn;
mpn = pn;
r_to_m = dist;
return;
}
for ( const auto& [ nn, w ] : edges[ cn ] )
{
if ( nn == pn ) continue;
FindMiddleNodeAndDist( nn, cn, dist + w );
}
}
void FindLongestDistToLeafNode( int cn, int pn, int dist )
{
if ( edges[ cn ].size() == 1 && cn != mn )
{
mx_dist = max( mx_dist, dist );
return;
}
for ( const auto& [ nn, w ] : edges[ cn ] )
{
if ( nn == pn ) continue;
FindLongestDistToLeafNode( nn, cn, dist + w );
}
}
int main()
{
ios::sync_with_stdio( 0 );
cin.tie(0);
cin >> n >> r;
for ( int i = 0; i < n - 1; ++i )
{
int f, t;
uint16_t w;
cin >> f >> t >> w;
edges[ f ].push_back( { t, w } );
edges[ t ].push_back( { f, w } );
}
FindMiddleNodeAndDist( r, -1, 0 );
FindLongestDistToLeafNode( mn, mpn, 0 );
//cout << mn << " ";
cout << r_to_m << " " << mx_dist;
}728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
| [G5] 백준 25603번 짱해커 이동식 C++ 매개변수 탐색 (0) | 2026.03.04 |
|---|---|
| [G5] 백준 15918번 랭퍼든 수열쟁이야!! C++ 백트래킹 (0) | 2026.03.02 |
| [G4] 백준 3803번 Networking C++ MST, 최소 스패닝 트리, 크루스칼 알고리즘 (0) | 2026.02.27 |
| [G3] 백준 13905번 세부 C++ MST, 최소 스패닝 트리 (0) | 2026.02.25 |
| [G5] 백준 23843번 콘센트 C++ 정렬, 우선순위 큐, 그리디 알고리즘 (0) | 2026.02.24 |
