전형적인 MST문제라서 크루스칼로 풀면 되는데

차이점은 마을을 두개로 나눈다는 점이다.

 

두개로 나누기 위해 대단한 일을 할 필요는 없고 마지막 제일 비싼 집 한개 남았을때 그냥 그 집만 연결 안해준다.

그리고 예외처리로 집이 2개밖에 없을땐 연결 안하면 마을 2개 되는거니까 answer = 0이 된다.

 

https://www.acmicpc.net/problem/1647

#include <bits/stdc++.h>
using namespace std;

vector<int> parent;

int Find(int x)
{
	if (parent[x] == x) return x;
	return parent[x] = Find(parent[x]);
}

void Union(int x, int y)
{
	x = Find(x);
	y = Find(y);
	if (x < y) parent[y] = x;
	else if (x > y) parent[x] = y;
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(NULL);

	int N, M;
	cin >> N >> M;

	if (N == 2) {
		cout << 0;
		return 0;
	}

	parent.resize(N + 1);
	for (int i = 1; i < N + 1; i++) {
		parent[i] = i;
	}

	vector<tuple<int, int, int>> costs(M); // cost, from, to
	int A, B, C;
	for (int i = 0; i < M; i++) {
		cin >> A >> B >> C;
		costs[i] = {C, A, B}; // sort 쉽게하려고 위치 바꿔주고
	}
	sort(costs.begin(), costs.end());

	int answer = 0, count = 0;
	for (auto t : costs) {
		int cost = get<0>(t);
		int from = get<1>(t);
		int to = get<2>(t);

		if (Find(from) != Find(to)) {
			answer += cost;
			Union(from, to);
			count++;		
		}

		if (count == N - 2) break; 
		// N - 1이면 모든 집 연결인데 N - 2라서 마지막 젤 비싼 집 연결 안해줌
	}

	cout << answer;

	return 0;
}