Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

hwooo

BOJ (C/C++) 1197번: 최소 스패닝 트리 본문

Study/Algorithm

BOJ (C/C++) 1197번: 최소 스패닝 트리

hwooo 2022. 12. 8. 05:31

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

 

1197번: 최소 스패닝 트리

첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이

www.acmicpc.net


풀이

최소 스패닝 트리를 구하는 문제이므로 union-find와 크루스칼 알고리즘을 사용했다.

(가중치 오름차순으로 정렬 후 작은 가중치 값부터 더하며 집합을 합쳐주었다.)

 

음수인 가중치가 있지만, 최단 경로를 구하는 게 아니라 크루스칼이 가능할 거라 판단했다.


코드

#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;

vector <pair<int, pair<int, int>>> G;
int root[10001];

int Find(int a) {
	if (root[a] == a) return a;
	return Find(root[a]);
}
void Union(int a, int b) {
	int roota, rootb;
	roota = Find(a);
	rootb = Find(b);
	root[rootb] = roota;
}

void Kruskal(int size) {
	int start, end, value;
	long long int sum = 0;

	for (int i = 0; i < size; i++) {
		value = G[i].first, start = G[i].second.first, end = G[i].second.second;

		// 같은 그룹에 속하면 계산할 필요 x
		if (Find(start) == Find(end)) continue;

		Union(start, end);
		sum += value;
	}

	printf("%lld", sum);
}
int main() {
	int V, E;
	int a, b, c;

	// input
	scanf("%d %d", &V, &E);
	for (int i = 0; i < E; i++) {
		scanf("%d %d %d", &a, &b, &c);
		G.push_back({ c,{a,b} });
	}

	// init
	for (int i = 1; i <= V; i++) root[i] = i; // 초기 루트는 자기 자신
	sort(G.begin(), G.end()); // 오름차순 정렬

	Kruskal(E);

	return 0;
}

'Study > Algorithm' 카테고리의 다른 글

BOJ (C/C++) 1629번: 곱셈  (0) 2022.12.09
BOJ (C/C++) 11723번: 집합  (0) 2022.12.08
BOJ (C/C++) 1976번: 여행 가자  (0) 2022.12.08
BOJ (C/C++) 13549번: 숨바꼭질 3  (0) 2022.12.08
BOJ (C/C++) 18111번: 마인크래프트  (0) 2022.12.08