parents 배열 : parents[x]
는 x가 가리키는 부모 노드를 나타냅니다. 이 부모노드를 따라가다가 더이상 부모가 없는 root 노드를 만난다면 해당 노드가 집합을 대표하는 원소가 됩니다.
int[] parents = new int[N]; // N은 총 원소의 개수
1. make : 각 원소에 대해 독립적인 집합으로 초기화합니다.
for (int i = 0; i < N; ++i) {
parents[i] = i;
}
2. find
int find(int x) {
if (x == parents[x]) {
return x;
}
/**
* (path compression)
* union 연산으로 대표 원소를 찾는데 가는 길이 멀어지는 경우를 방지하기 위해
* 대표 원소를 바로 가리키도록 만든다.
*/
return parents[x] = find(parents[x]);
}
3. union
void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
parents[rootX] = rootY;
}
}
전체 코드 및 실행 예시
class UnionFind {
int[] parents; // parents[x] : x가 속한 집합의 대표 원소
/* make 연산 (각 집합을 자기 자신 1개만 있는 집합으로 생성) */
UnionFind(int N) {
parents = new int[N];
for (int i = 0; i < N; ++i) {
parents[i] = i;
}
}
/* find 연산 */
public int find(int x) {
if (x == parents[x]) {
return x;
}
/**
* (path compression)
* union 연산으로 대표 원소를 찾는데 가는 길이 멀어지는 경우를 방지하기 위해
* 대표 원소를 바로 가리키도록 만든다.
*/
return parents[x] = find(parents[x]);
}
/* union */
public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
/* x와 y가 서로 다른 서로소 집합에 속해 있는 경우 */
if (rootX != rootY) {
parents[rootX] = rootY;
}
}
}
public class Main {
public static void main(String[] args) {
UnionFind uf = new UnionFind(5);
uf.union(0, 1);
uf.union(1, 2);
uf.union(3, 4);
System.out.println("0과 3이 연결되어 있나요?");
System.out.print(">> ");
if (uf.find(0) == uf.find(3)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
System.out.println("\n- 1이 속한 집합과 4가 속한 집합 연결\n");
uf.union(1, 4);
System.out.println("0과 3이 연결되어 있나요?");
System.out.print(">> ");
if (uf.find(0) == uf.find(3)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
출력 결과
0과 3이 연결되어 있나요?
>> NO
- 1이 속한 집합과 4가 속한 집합 연결
0과 3이 연결되어 있나요?
>> YES
정점 과 에 새로운 간선을 추가하려는데
find(v1) == find(v2)
라면
→ 이미 다른 간선으로 연결되어 같은 집합에 속한다는 뜻이고, 과 를 잇는 간선을 추가한다면 사이클이 형성됩니다.
SWEA 알고리즘 문제 중 union find를 위해 존재하는 문제가 있습니다. union find 는 이해하는 난이도에 비해 구현이 간단한 편이므로 이해를 완료하셨다면 쉽게 이 문제를 해결할 수 있을 것입니다.
swea 3289 서로소 집합
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWBJKA6qr2oDFAWr
Union Find 알고리즘은 그래프 이론에서 기본적이면서도 강력한 도구로, 복잡한 연결성 문제를 간단하고 효율적으로 해결할 수 있습니다. 위 연습 문제로 직접 구현해보고 실전에서도 활용해보시길 바랍니다!
https://github.com/leepro1 추천으로 들렀습니다.
잘 읽고 갑니다 ^~^