Baekjoon/Gold

C++ / 백준 / 1717 / 집합의 표현

GitHubSeob 2024. 6. 5. 17:20
문제

 

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

 

 

문제풀이

 

숫자 두 개가 속한 집합을 합치거나, 같은 집합인지 확인을 하는 유니온 파인드의 기본 문제이다.

집합 중 가장 작은 수를 나타내는 parent 벡터를 이용한다.

집합의 가장 작은 수를 찾는 find 함수, 두 집합을 합치는 Union함수, 두 숫자가 같은 집합인지 확인하면 isUnion함수를 선언한다.

 

int find(vector<int>&parent, int num) {
	if (parent[num] == num) return num;
	return parent[num] = find(parent, parent[num]);
}

집합의 가장 작은 수가 num과 같다면 바꿀 필요가 없으므로 그대로 둔다.

그렇지 않으면 parent[num]을 가장 작은 값으로 바꾼다.

ex) parent[3]=2, parent[5]=3 이라면 parent[5]=2

 

void Union(vector<int>&parent, int num1, int num2) {
	num1 = find(parent, num1), num2 = find(parent, num2);
	if (num1 == num2) return;
	if (num1 < num2) swap(num1, num2);
	parent[num1] = num2;
}

두 숫자의 집합을 합치는 함수이다.

먼저 숫자의 집합 중 가장 작은 숫자를 각각 찾는다.

둘이 같은 집합이라면 넘어간다.

그렇지 않으면 집합의 값은 작은 값이 되어야 하므로 두 숫자를 바꾼다.

그다음 parent[큰수] = 작은 수로 바꾼다.

 

bool isUnion(vector<int>&parent, int num1, int num2) {
	if (find(parent, num1) == find(parent, num2)) return true;
	return false;
}

둘이 같은 집합인지 확인하는 함수이다.

find함수를 사용하여 둘의 값이 같다면 같은 집합이므로 true를, 다르다면 false를 return 하면 된다.

 

코드
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int find(vector<int>&parent, int num) {
	if (parent[num] == num) return num;
	return parent[num] = find(parent, parent[num]);
}

void Union(vector<int>&parent, int num1, int num2) {
	num1 = find(parent, num1), num2 = find(parent, num2);
	if (num1 == num2) return;
	if (num1 < num2) swap(num1, num2);
	parent[num1] = num2;
}

bool isUnion(vector<int>&parent, int num1, int num2) {
	if (find(parent, num1) == find(parent, num2)) return true;
	return false;
}

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

	int N(0), M(0);
	cin >> N >> M;
	vector<int>parent(N + 1, 0);
	for (int idx = 0; idx <= N; ++idx) parent[idx] = idx;

	for (int idx = 0; idx < M; ++idx) {
		int cmd(0), num1(0), num2(0);
		cin >> cmd >> num1 >> num2;
		if (cmd == 0) Union(parent, num1, num2);
		else if (cmd == 1) isUnion(parent, num1, num2) ? cout << "YES\n" : cout << "NO\n";
	}
}