문제풀이/백준oj
[백준OJ] 18769번 그리드 네트워크
Hyeon-Uk
2021. 7. 29. 22:52
반응형
https://www.acmicpc.net/problem/18769
18769번: 그리드 네트워크
재현이는 그리드 네트워크 컨설팅 회사를 운영하고 있다. 어떤 회사의 데이터 서버가 격자 형태의 그래프로 주어졌을 때, 최소의 비용을 들여서 전용 통신망을 설치하려고 한다. 이때, 전용 통
www.acmicpc.net
-풀이-
파인드-유니온을 이용해서 그래프이론중, MST를 이용하여 풀었다.
먼저 edge들을 모두 받은뒤, 가중치값을 기준으로 오름차순정렬을 해준다.
그런뒤 모든 구역을 자신한정으로 초기설정을 해준뒤, 정렬된 edge를 탐색하며, edge로 연결된 두 정점이 같은 구역에 있지 않다면, 가중치의 값을 더해주고, 두 정점을 union_parent를 이용하여 같은 구역으로 합쳐준다.
이렇게 모든 edge들을 탐색하면 MST가 완성이 되고, 최소설치비용을 구할 수 있다.
-시간복잡도-
초기 셋팅 (parent배열 초기화 및 입력) = O(RC)
edge벡터 정렬 = 원소의 개수가 (R-1)*C + R*(C-1)개 이므로, 대략 2RC개가 된다. 따라서 정렬에 걸리는 시간은 O(RC log RC) 가 된다.
MST알고리즘은 경로를 압축한 FIND 알고리즘으로 인해O(1)시간이 걸리고, UNION_PARENT에 O(1) 이 걸리므로, 원소의 개수만큼 시간이 든다. 따라서 O(RC)가 된다.
따라서 최종 시간복잡도는 O(RClogRC)가 된다.
-코드-
#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;
pair<int,int> parent[501][501];
vector<pair<pair<pair<int,int>, pair<int,int>>,int>> edge;
int r, c,t;
bool compare(pair<pair<pair<int, int>, pair<int, int>>, int> a, pair<pair<pair<int, int>, pair<int, int>>, int> b) {
return a.second < b.second;
}
pair<int,int> find(pair<int,int> a) {
if (a == parent[a.first][a.second]) {
return a;
}
else {
return parent[a.first][a.second]=find(parent[a.first][a.second]);
}
}
void union_parent(pair<int,int> a, pair<int, int> b) {
a = find(a);
b = find(b);
if (a < b) {
parent[b.first][b.second] = a;
}
else {
parent[a.first][a.second] = b;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> t;
while (t--) {
cin >> r >> c;
edge.clear();
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
parent[i][j] = { i,j };
}
}
for (int i = 1; i <= r; i++) {
for (int j = 1; j < c; j++) {
int cost;
cin >> cost;
edge.push_back({ {{i,j},{i,j + 1}},cost });
}
}
for (int i = 1; i < r; i++) {
for (int j = 1; j <= c; j++) {
int cost;
cin >> cost;
edge.push_back({ {{i,j},{i + 1,j}},cost });
}
}
sort(edge.begin(), edge.end(), compare);
int total = 0;
for (int i = 0; i < edge.size(); i++) {
pair<int, int> a, b;
int cost;
a = edge[i].first.first;
b = edge[i].first.second;
cost = edge[i].second;
if (find(a) != find(b)) {
union_parent(a, b);
total += cost;
}
}
cout << total << "\n";
}
return 0;
}
반응형