728x90
반응형
1774번: 우주신과의 교감
(1,1) (3,1) (2,3) (4,3) 이렇게 우주신들과 황선자씨의 좌표가 주어졌고 1번하고 4번이 연결되어 있다. 그렇다면 1번하고 2번을 잇는 통로를 만들고 3번하고 4번을 잇는 통로를 만들면 신들과 선자씨끼
www.acmicpc.net
지금까지와는 다르게, 가중치가 주어지지 않고 점과 점 사이의 거리가 가중치인 문제였다.
크루스칼을 구현하는 능력이 부족한 것 같아, 크루스칼 알고리즘을 이용해서 구현해봤다.
알고리즘 설계
- 노드의 번호, x, y 좌표를 저장해준다.
- 저장한 노드들 사이에 모든 간선을 구한다. 간선 = { A노드, B노드, A와 B 사이의 거리 (가중치) }
- 구한 간선들을 가중치를 기준으로 오름차순 정렬해준다.
- 사이클이 생기지 않게 간선을 선택하여 MST를 만들고 비용을 구한다.
- union-find + memoization
코드
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ulli;
// 위치와 아이디를 가진 구조체
struct Node
{
pair<int, int> pos;
int id;
};
// 간선 구조체
struct Edge
{
int a, b;
double dist;
bool operator < (const Edge& e) const
{
return dist < e.dist;
}
};
int parents[1001];
vector<Node> nodes;
vector<Edge> edges;
// union-find
int find(int v)
{
vector<int> memo;
while (parents[v] != v)
{
v = parents[v];
memo.push_back(v);
}
for (int i : memo)
parents[i] = v;
return v;
}
bool uni(int a, int b)
{
int fa = find(a), fb = find(b);
if (fa != fb)
{
parents[fa] = fb;
return true;
}
return false;
}
// 점과 점 사이의 거리 구하기
double GetDist(pair<int, int> p1, pair<int, int> p2)
{
return sqrt((ulli)pow(p1.first - p2.first, 2) + (ulli)pow(p1.second - p2.second, 2));
}
int main()
{
int vCnt, lCnt, x, y;
double result = 0;
cin >> vCnt >> lCnt;
// 각 노드의 위치를 입력 받는다
for (int i = 1; i <= vCnt; i++)
{
cin >> x >> y;
parents[i] = i;
nodes.push_back(Node{ {x, y}, i });
}
// 이미 정해진 경로를 입력 받는다
for (int i = 0; i < lCnt; i++)
{
cin >> x >> y;
uni(x, y);
}
// 만들 수 있는 모든 간선을 만들어
// Edge 벡터에 넣는다
for (int i = 0; i < vCnt; i++)
{
for (int j = 0; j < vCnt; j++)
{
if (i == j) continue;
double dist = GetDist(nodes[i].pos, nodes[j].pos);
edges.push_back({ nodes[i].id, nodes[j].id, dist });
}
}
// 오름차순 정렬
// 크루스칼
sort(edges.begin(), edges.end());
// 사이클이 생기지 않게 가중치를 더함
for (int i = 0; i < edges.size(); i++)
{
if (uni(edges[i].a, edges[i].b))
{
result += edges[i].dist;
}
}
// 소수점 둘째 자리까지 출력
cout << fixed;
cout.precision(2);
cout << result;
}
오랜만에 MST 문제를 풀고, 더해 어렵지 않은 수학적 개념까지 들어간 문제를 풀어서 기분이 좋았다!!
728x90
반응형
'알고리즘 문제풀이 > 그래프 탐색' 카테고리의 다른 글
[백준][C++] 6497 전력난 (0) | 2022.11.03 |
---|---|
[백준][C++] 14621 나만 안되는 연애 (0) | 2022.11.03 |
[백준][C++] 21924 도시 건설 (0) | 2022.11.03 |
[백준][C++] 16398 행성 연결 (0) | 2022.11.03 |
[백준][C++] 1647 도시 분할 계획 (0) | 2022.11.03 |