BOJ 16398. 행성 연결
1. 문제설명
- 행성
T
에서N
개의 행성 간에 플로우를 설치하려고 한다. - 모든 행성을 연결하면서 플로우 관리 비용을 최소화 하려 한다.
-
행성
i
와 행성j
사이의 플로우 관리비용은 $C_ij$이며,i = j
인 경우 항상 0이다. - 문제 분류
- Graph, MST
2. 알고리즘 설계
- 최소신장트리 문제이다.
- 간선과 간선 간 비용을 입력받고 정렬한다.
- 두 노드의 부모가 같지 않다면, 연결해주면 된다.
- 결과값이 int 범위를 초과할 수 있으니, long long 형으로 선언해야 한다.
3. 전체 코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
int parent[1001];
int cost[1001][1001];
vector<pair<int, pair<int, int>>> edge;
int FindParent(int x){
if(x == parent[x])
return x;
return parent[x] = FindParent(parent[x]);
}
bool SameParent(int x, int y){
x = FindParent(x);
y = FindParent(y);
if(x == y)
return true;
return false;
}
void Merge(int x, int y){
x = FindParent(x);
y = FindParent(y);
if(x == y)
return;
parent[x] = y;
}
int main(){
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// input
cin >> n;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cin >> cost[i][j];
}
}
// init
for(int i = 1; i <= n; i++)
parent[i] = i;
// edge
for(int i = 1; i <= n; i++){
for(int j = i + 1; j <= n; j++){
edge.push_back(make_pair(cost[i][j], make_pair(i, j)));
}
}
// Make MST
long long ans = 0;
sort(edge.begin(), edge.end());
for(int i = 0; i < edge.size(); i++){
if(!SameParent(edge[i].second.first, edge[i].second.second)){
ans += edge[i].first;
Merge(edge[i].second.first, edge[i].second.second);
}
}
cout << ans << '\n';
}