코딩테스트 사이트 : 백준
난이도 : 골드4
풀이 날짜 : 2022.06.25
사용한 풀이 방법 : UnionFind
https://www.acmicpc.net/problem/1717
예를 들어 각각 독립적으로 자유분방하게 여러 노드가 존재한다고 가정하자
아래 그림은 6개의 노드가 존재하고, 모두 자기 자신을 가리킨다고 할 수가 있다.
1번 노드와 2번 노드가 연결되었다고 해본다.
Union
이라고 한다.이번에는 2번과 3번 노드가 연결 되었다고 해보자.
여기서 유니온 파인드의 핵심,
1번 노드와 3번 노드는 같은 그래프에 있는데, 어떻게 연결되었다고 파악할 수 있을까요?
재귀함수
로 확인을 한다. Union-Find
라고 한다.코드로 보면 이해가 될 것이다.
// 부모 노드 얻기
public static int getParent(int[] parent, int x){
if(parent[x] == x) return x; // 자기자신을 가리킨다면 반환
return parent[x] = getParent(parent, parent[x]);
}
// 두 부모 노드 합치기
public static void unionParent(int[] parent, int x, int y){
x = getParent(parent, x);
y = getParent(parent, y);
if(x > y) parent[x] = y;
else parent[y] =x ;
}
public static boolean findParent(int[] parent, int x, int y){
x = getParent(parent, x);
y = getParent(parent, y);
return x == y;
//풀어 쓰면,
//if(x==y) return true;
//else return false;
}
이제 작성한 코드를 테스트 해보자
아래와 같이 문제가 주어졌을 때, 풀어 보자
import java.util.Arrays;
public class unionFindTest {
// 부모노드 얻기
public static int getParent(int[] parent, int x){
if(parent[x] == x) return x;
return parent[x] = getParent(parent, parent[x]);
}
// 두 부모 노드 합치기
public static void unionParent(int[] parent, int x, int y){
x = getParent(parent, x);
y = getParent(parent, y);
if(x > y) parent[x] = y;
else parent[y] =x ;
}
// 부모가 같은지 확인 -> 즉, 같이 연결되어 있는지 확인
public static boolean findParent(int[] parent, int x, int y){
x = getParent(parent, x);
y = getParent(parent, y);
return x == y;
}
// 테스트 코드
public static void main(String[] args) {
int[] parent = new int[7];
for(int i =1 ; i< parent.length; i++){
parent[i] = i; // 모든 부모노드 초기화
}
unionParent(parent, 1,2);
unionParent(parent, 2,3);
unionParent(parent, 3,4);
unionParent(parent, 5,6);
findParent(parent, 1,4); // true
findParent(parent, 4,5); // false
}
}
각 부분마다 System.out.println(Arrays.toString(parent));
넣어주면 아래와 같다.
그래서 결론적으로 parent 배열
은 아래와 같이 만들어 진다.
0
이면 합집합 연산을, 1
이면 같은 집합안에 있는지 유무를 리턴한다.1
일때만 하면 된다.1 1 7
로 같은 집합안에 있는지 유무를 파악해야한다. 1
과 7
은 연결되어 있지 않음을 알 수 있다 NO
를 출력한다.1 7 1
로 같은 집합안에 있는지 유무를 파악해야한다. 1
과 7
은 연결되어 있지 않음을 알 수 있다 NO
를 출력한다.1 1 1
로 같은 집합안에 있는지 유무를 파악해야한다.1
과 1
은 연결되어 있음을 알 수 있다YES
를 출력한다. import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[] parent = new int[N+1];
for(int i =0 ; i< parent.length; i++){
parent[i] = i;
}
int order;
int x;
int y;
StringBuilder sb =new StringBuilder();
// 한줄 한줄 M번 읽기
for(int i=0; i<M; i++){
st = new StringTokenizer(br.readLine());
order = Integer.parseInt(st.nextToken());
x = Integer.parseInt(st.nextToken());
y = Integer.parseInt(st.nextToken());
if(order == 0){
unionParent(parent, x,y);
}
if(order == 1){
if(findParent(parent,x,y)) sb.append("YES");
else sb.append("NO");
sb.append("\n");
}
}
System.out.println(sb.toString());
br.close();
}
// 부모노드 얻기
public static int getParent(int[] parent, int x){
if(parent[x] == x) return x;
return parent[x] = getParent(parent, parent[x]);
}
// 두 부모 노드 합치기
public static void unionParent(int[] parent, int x, int y){
x = getParent(parent, x);
y = getParent(parent, y);
if(x > y) parent[x] = y;
else parent[y] =x ;
}
// 부모가 같은지 확인 -> 즉 같이 연결되어 있는지 확인
public static boolean findParent(int[] parent, int x, int y){
x = getParent(parent, x);
y = getParent(parent, y);
return x == y;
}
}