※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 10379번 문제인 Hiking in the Hills이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/10379
어떤 정수점 경로가 있을 때, 해당 경로가 지나는 점을 각 점이 존재하는 삼각형 면 위에서 적절하게 옮겨 경로의 최고점을 증가시키지 않고 삼각형의 꼭짓점으로 이동시킬 수 있다. 따라서, 시작점과 끝점을 제외한 모든 점이 주어진 꼭짓점들로만 구성된 경로가 존재한다.
따라서, 시작점과 끝점을 그 점이 포함된 삼각형의 꼭짓점들로 한 번 연결하고, 주어진 꼭짓점들을 높이가 낮은 순으로 정렬하고, 각 점을 하나씩 추가하면서 MST를 구성하듯이 최적 높이의 경로를 찾아 문제를 해결하자.
시작점과 끝점이 원래의 꼭짓점 또는 변의 위에 있는 경우 예외처리가 필요함에 유의하자.
아래는 제출한 소스코드이다.
//MST 응용구현
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
int uf[3000];
int findf(int cur) {
if (cur == uf[cur]) return cur;
return uf[cur] = findf(uf[cur]);
}
ll AREA(pair<int, int> &p1, pair<int, int> &p2, pair<int, int> &p3) {
return abs((ll)p1.first * p2.second + (ll)p2.first * p3.second + (ll)p3.first * p1.second - (ll)p1.first * p3.second - (ll)p2.first * p1.second - (ll)p3.first * p2.second);
}
int N, mS, mE, X, Y, Z;
int H[3000];
int midx;
map<pair<int, int>, int> mp;
pair<int, int> invmp[3000];
vector<pair<int, pair<int, int>>> E;
vector<pair<int, pair<int, int>>> T;
vector<int> G[3000];
int gparent[3000];
void dfs(int cur, int par) {
gparent[cur] = par;
for (auto &nxt:G[cur]) {
if (nxt == par) continue;
dfs(nxt, cur);
}
}
vector<int> ans;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for (int i = 0; i < N; i++) {
int X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3; cin >> X1 >> Y1 >> Z1 >> X2 >> Y2 >> Z2 >> X3 >> Y3 >> Z3;
int idx1, idx2, idx3;
if (!mp.count(make_pair(X1, Y1))) {
mp[make_pair(X1, Y1)] = midx;
invmp[midx] = make_pair(X1, Y1);
H[midx] = Z1;
midx++;
}
idx1 = mp[make_pair(X1, Y1)];
if (!mp.count(make_pair(X2, Y2))) {
mp[make_pair(X2, Y2)] = midx;
invmp[midx] = make_pair(X2, Y2);
H[midx] = Z2;
midx++;
}
idx2 = mp[make_pair(X2, Y2)];
if (!mp.count(make_pair(X3, Y3))) {
mp[make_pair(X3, Y3)] = midx;
invmp[midx] = make_pair(X3, Y3);
H[midx] = Z3;
midx++;
}
idx3 = mp[make_pair(X3, Y3)];
E.emplace_back(make_pair(max(Z1, Z2), make_pair(idx1, idx2)));
E.emplace_back(make_pair(max(Z2, Z3), make_pair(idx2, idx3)));
E.emplace_back(make_pair(max(Z3, Z1), make_pair(idx3, idx1)));
T.emplace_back(make_pair(idx1, make_pair(idx2, idx3)));
}
cin >> X >> Y >> Z;
if (mp.count(make_pair(X, Y))) mS = mp[make_pair(X, Y)];
else {
auto S = make_pair(X, Y);
mS = mp[S] = midx;
invmp[midx] = S;
H[midx] = Z;
for (auto p:T) {
int idx1 = p.first, idx2 = p.second.first, idx3 = p.second.second;
auto p1 = invmp[idx1], p2 = invmp[idx2], p3 = invmp[idx3];
ll A = AREA(p1, p2, p3);
ll A1 = AREA(p1, p2, S), A2 = AREA(p2, p3, S), A3 = AREA(p3, p1, S);
if (A == A1 + A2 + A3) {
E.emplace_back(make_pair(H[idx1], make_pair(idx1, midx)));
E.emplace_back(make_pair(H[idx2], make_pair(idx2, midx)));
E.emplace_back(make_pair(H[idx3], make_pair(idx3, midx)));
}
}
midx++;
}
cin >> X >> Y >> Z;
if (mp.count(make_pair(X, Y))) mE = mp[make_pair(X, Y)];
else {
auto S = make_pair(X, Y);
mE = mp[S] = midx;
invmp[midx] = S;
H[midx] = Z;
for (auto p:T) {
int idx1 = p.first, idx2 = p.second.first, idx3 = p.second.second;
auto p1 = invmp[idx1], p2 = invmp[idx2], p3 = invmp[idx3];
ll A = AREA(p1, p2, p3);
ll A1 = AREA(p1, p2, S), A2 = AREA(p2, p3, S), A3 = AREA(p3, p1, S);
if (A == A1 + A2 + A3) {
E.emplace_back(make_pair(H[idx1], make_pair(idx1, midx)));
E.emplace_back(make_pair(H[idx2], make_pair(idx2, midx)));
E.emplace_back(make_pair(H[idx3], make_pair(idx3, midx)));
}
}
midx++;
}
for (int i = 0; i < midx; i++) uf[i] = i;
sort(E.begin(), E.end());
for (auto &p:E) {
if (findf(mS) == findf(mE)) break;
int x = p.second.first, y = p.second.second;
int xx = findf(x), yy = findf(y);
if (xx != yy) {
uf[yy] = xx;
G[x].emplace_back(y);
G[y].emplace_back(x);
}
}
dfs(mS, mS);
while (mE != mS) {
ans.emplace_back(mE);
mE = gparent[mE];
}
ans.emplace_back(mS);
cout << ans.size() << '\n';
reverse(ans.begin(), ans.end());
for (auto &idx:ans) {
cout << invmp[idx].first << ' ' << invmp[idx].second << ' ' << H[idx] << '\n';;
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 1999 // C++] 최대최소 (0) | 2024.08.24 |
---|---|
[BOJ 3165 // C++] 5 (0) | 2024.08.23 |
[BOJ 12111 // C++] Turnir (0) | 2024.08.21 |
[BOJ 25989 // C++] Jabbing Jets (0) | 2024.08.20 |
[BOJ 25984 // C++] Extended Braille (0) | 2024.08.19 |