개인사
[G3] 백준 13905번 세부 C++ MST, 최소 스패닝 트리 본문
728x90

리뷰

https://www.acmicpc.net/problem/13905
최대값의 최소를 구하는 스패닝 트리 문제
전역 변수
- N : 배열의 최대 크기를 정의할 상수 변수
- n : 노드의 개수를 저장할 변수
- m : 간선의 개수를 저장할 변수
- sn : 시작 노드의 번호를 저장할 변수
- en : 도착 노드의 번호를 저장할 변수
- Edge : 간선 정보를 정의할 구조체, 가중치를 기준으로 내림차순 정렬한다.
- edges : 간선 정보를 저장할 Edge타입 벡터
- nodes : 각 노드가 속한 그룹의 번호를 저장할 배열
함수
1. Find
int Find( int a ) {
if (nodes[a] == a) return a;
return nodes[a] = Find( nodes[a] );
}
노드가 속한 그룹의 번호를 찾고, 경로 압축을 수행해 주기 위한 함수
2. Union
bool Union( int a, int b ) {
int A = Find( a );
int B = Find( b );
if (A == B) return false;
nodes[B] = A;
return true;
}
두 노드가 속한 그룹의 번호를 찾고, 같다면 false를, 다르다면 그룹을 합쳐준 후 true를 반환하는 함수
문제풀이
- n, m, sn, en값을 입력 받고, m개의 간선 정보를 입력 받아 edges벡터를 초기화한다.
- sort함수를 통해 edges벡터를 가중치를 기준으로 내림차순 정렬한다.
- nodes배열을 자기 자신을 값을 같도록 초기화한다.
- 변수 mn을 100만보다 큰 값으로 초기화한다.
- edges를 순회하며 변수 a, b, w에 구조체 정보를 파싱한다.
- Union함수에 a, b를 전달하고, 반환값이 true인 경우 mn을 w와 비교해 더 작은 값으로 변경한다.
- 만약 Find(sn)과 Find(en)의 반환값이 같다면 break처리한다.
- 최종적으로 Find(sn)과 Find(en)의 반환값이 같다면 mn을, 다르다면 0을 출력한다.
트러블 슈팅
- sn에서 en으로 갈 수 있는 길이 보장되어 있다고 생각하여 로직 작성 후 제출 시 WA를 받았다.
- 만약 sn과 en이 같은 그룹에 속해있지 않는다면 도달할 수 없는 것으로 생각하여 로직 수정 후 제출 시 AC를 받았다.
참고 사항
- 다리의 무게제한은 최소 1부터 최대 100만이다.
- 숭이가 출발하여 혜빈이의 위치까지 도달할 수 있다는 보장이 없다.
정답 코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5 + 1;
int n, m, sn, en;
struct Edge {
int a, b, w;
bool operator<( const Edge& edge ) const {
return w > edge.w;
}
};
vector<Edge> edges;
int nodes[N];
int Find( int a ) {
if (nodes[a] == a) return a;
return nodes[a] = Find( nodes[a] );
}
bool Union( int a, int b ) {
int A = Find( a );
int B = Find( b );
if (A == B) return false;
nodes[B] = A;
return true;
}
int main() {
ios::sync_with_stdio( 0 );
cin.tie( 0 );
cin >> n >> m >> sn >> en;
while (m--) {
int a, b, w; cin >> a >> b >> w;
edges.push_back( { a, b, w } );
}
sort( edges.begin(), edges.end() );
for (int i = 1; i <= n; ++i) nodes[i] = i;
int mn = 2e9;
for (const Edge& edge : edges) {
int a = edge.a, b = edge.b, w = edge.w;
if (Union( a, b )) {
mn = min( mn, w );
if (Find( sn ) == Find( en )) break;
}
}
cout << (Find( sn ) != Find( en ) ? 0 : mn);
}728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
| [G4] 백준 20924번 트리의 기둥과 가지 C++ 트리, DFS, 깊이 우선 탐색 (0) | 2026.03.01 |
|---|---|
| [G4] 백준 3803번 Networking C++ MST, 최소 스패닝 트리, 크루스칼 알고리즘 (0) | 2026.02.27 |
| [G5] 백준 23843번 콘센트 C++ 정렬, 우선순위 큐, 그리디 알고리즘 (0) | 2026.02.24 |
| [G3] 백준 1833번 고속철도 설계하기 C++ 정렬, 유니온 파인드, MST, 최소 스패닝 트리 (0) | 2026.02.20 |
| [S3] 백준 17952번 과제는 끝나지 않아! C++ 스택 (0) | 2026.02.19 |
