본문 바로가기

Problem Solving/BaekJoon

4386 별자리 만들기

 

4386번: 별자리 만들기

도현이는 우주의 신이다. 이제 도현이는 아무렇게나 널브러져 있는 n개의 별들을 이어서 별자리를 하나 만들 것이다. 별자리의 조건은 다음과 같다. 별자리를 이루는 선은 서로 다른 두 별을 일

www.acmicpc.net

전형적인 Minimum Spanning Tree 문제이다.

입력으로 별의 x, y 좌표를 받아서 Complete Graph가 되도록 모든 별들 사이의 간선을 만들어준다.

그리고 이제부턴 크루스칼 알고리즘을 적용해서 간선을 정렬해서 최소 비용의 간선부터

루프를 생성하지 않으면 선택하는 식으로 풀면 된다.

 

간단한 문제였는데, 오랜만에 풀다 보니 사소한 데서 에러가 좀 있었다. 그리고 코드도 좀 더럽게 짠 거 같기도 하고...

꾸준히 풀어야 겠다.

C++

 

더보기
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

using mypair = pair<double, double>;

struct edge {
	int node1, node2;
	double cost;
};

vector<int> parent;

int find_parent(int curr) {
	if (curr == parent[curr])
		return curr;
	while (parent[curr] != curr)
		curr = parent[curr];
	return curr;
}

int main(void)
{
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);

	int n;
	cin >> n;

	vector<mypair> vec(n);
	parent = vector<int>(n);

	for (int i = 0; i < n; ++i) {
		cin >> vec[i].first >> vec[i].second;
		parent[i] = i;
	}

	vector<edge> edges;
	auto get_cost = [](mypair a, mypair b) {return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2)); };

	for(int i=0;i<n;++i)
		for (int j = i + 1; j < n; ++j) {
			edges.push_back({ i,j,get_cost(vec[i],vec[j]) });
		}

	sort(edges.begin(), edges.end(), [](edge a, edge b) {return a.cost < b.cost; });

	double cost{};
	int cnt{};

	for (auto& e : edges) {
		int p1 = find_parent(e.node1), p2 = find_parent(e.node2);
		if (p1 == p2)
			continue;
		cost += e.cost;
		if (++cnt == n)
			break;
		if (p1 < p2)
			parent[p2] = p1;
		else
			parent[p1] = p2;
	}

	cout << cost;
	
	return 0;
}
728x90

'Problem Solving > BaekJoon' 카테고리의 다른 글

2056 작업  (0) 2021.02.06
1987 알파벳  (0) 2021.02.02
1806 부분합  (0) 2021.02.02
2228 구간 나누기  (0) 2021.01.15
2624 동전 바꿔주기  (0) 2021.01.12