[BOJ] #1717 - 집합의 표현
👻 집합의 표현
🌱 문제
초기에 n + 1개의 집합 {0}, {1}, {2}, …, {n}이 있다. 여기에 합집합 연산과, 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산을 수행하려고 한다.
집합을 표현하는 프로그램을 작성하시오.
- 시간 제한 : 2초
- 메모리 제한 : 128 MB
🌱 입력
첫째 줄에 n, m이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는 a가 포함되어 있는 집합과, b가 포함되어 있는 집합을 합친다는 의미이다. 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산은 1 a b의 형태로 입력이 주어진다. 이는 a와 b가 같은 집합에 포함되어 있는지를 확인하는 연산이다.
🌱 출력
1로 시작하는 입력에 대해서 a와 b가 같은 집합에 포함되어 있으면 “YES” 또는 “yes”를, 그렇지 않다면 “NO” 또는 “no”를 한 줄에 하나씩 출력한다.
🌱 제한
- 1 ≤ n ≤ 1,000,000
- 1 ≤ m ≤ 100,000
- 0 ≤ a, b ≤ n
- a, b는 정수
- a와 b는 같을 수도 있다.
🌱 예제
🪐 입출력 1
- 입력
    7 8 0 1 3 1 1 7 0 7 6 1 7 1 0 3 7 0 4 2 0 1 1 1 1 1
- 출력
    NO NO YES
👻 풀이
#include <iostream>
#include <vector>
using namespace std;
class DisjointSet
{
public:
    DisjointSet(int n) : _parent(n), _rank(n, 0)
    {
        for (int i = 0; i < n; i++)
            _parent[i] = i;
    }
    int Find(int u)
    {
        if (u == _parent[u])
            return u;
        return _parent[u] = Find(_parent[u]);
    }
    void Union(int u, int v)
    {
        u = Find(u);
        v = Find(v);
        if (u == v)
            return;
        if (_rank[u] > _rank[v])
            swap(u, v);
        
        _parent[u] = v;
        if (_rank[u] == _rank[v])
            _rank[v]++;
    }
private:
    vector<int> _parent;
    vector<int> _rank;
};
int main()
{
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	// 집합의 표현
    int n, m, a, b, c;
    cin >> n >> m;
    DisjointSet sets(n + 1);
    while (m--)
    {
        cin >> c >> a >> b;
        if (c)
        {
            int u = sets.Find(a);
            int v = sets.Find(b);
            if (u == v)
                cout << "YES\n";
            else
                cout << "NO\n";
        }
        else
        {
            sets.Union(a, b);
        }
    }
    return 0;
}
- 시간 : 40 ms
- 메모리 : 9836 KB
👻 글을 마치며
방금 막 최소 스패닝 트리를 공부하고 바로 푼 알고리즘 문제였는데 생각보다 쉽게 풀었던 것 같다. 그래도 아직까지는 안 보고 코드 작성하는 게 95%, 보고 작성하는 부분이 5% 정도 되는 것 같은데, 보고 작성하는 부분이 0% 될 때까지 반복 학습을 해야할 것 같다.
 
      
    
Leave a comment