programming language/Algorithm

[Greedy Approach 예제] 백준 1197 (kruskal)

jellylucy 2021. 8. 17. 11:53

문제

 

1197번: 최소 스패닝 트리

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

www.acmicpc.net


문제 풀이

int parent[10001];

struct edge {
	int u, v, w;
	edge(int u, int v, int w) {
		this->u = u;
		this->v = v;
		this->w = w;
	}
};

//initial : n개의 부분집합을 초기화하고 하나의 원소들이 들어가잇도록 한다.
//find(i) : point 만들기 
int find(int u) {
	if (u == parent[u])
		return u;
	return parent[u] = find(parent[u]);
}

void merge(int u, int v) {
	u = find(u);
	v = find(v);

	parent[v] = u;
}
int compare_comp(const edge& a, const edge& b) {
	return a.w < b.w;//edge값은 세번째 인자이니까.
}
int main() {
	cin >> V >>  E;
	vector<edge> v;

	for (int i = 1; i <= V; i++) {
		parent[i] = i;
	}//(1) vertex들의 모임, Initial(). 하나의 set에 하나의 원소들어간다.
	int A, B, C;
	for (int i = 0; i < E; i++) {
		cin >> A >> B >> C;
		v.push_back(edge(A, B, C));
	}

	sort(v.begin(), v.end(), compare_comp);//(2) edge 오름차순 정렬

	for (auto vertex : v) {
		if (find(vertex.v) != find(vertex.u)) {//(3) 같은 set에 있는지 확인한다.
			merge(vertex.u, vertex.v);//(4) 다른 set인 경우 merge
			ans += vertex.w;//
		}
	}
	cout << ans;
	return 0;

find, merge 함수

int find(int u) {
	if (u == parent[u])
		return u;
	return parent[u] = find(parent[u]);
}

void merge(int u, int v) {
	u = find(u);
	v = find(v);

	parent[v] = u;
}

find() : 해당 원소가 어느 set에 있는지 찾고 set의 부모노드를 반환한다

merge() : 찾은 두개의 원소를 같은 set에 넣어야 한다. 두번째 노드의 부모노드를 첫번째 원소로 대입해 연결시킨다.