Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 구현
- sw expert academy
- 컴퓨터구조
- Comparable
- 표 편집
- 순열
- 베스트 앨범
- 토마토
- Comparator
- 고정소수점
- 메뉴 리뉴얼
- 조합
- 데이터
- 부동소수점
- 자바
- 도둑질
- 기능 개발
- swea
- 다단계 칫솔 판매
- 오블완
- 괄호 회전하기
- 프로그래머스
- 코테
- java
- 요세푸스
- Call-by-Value
- 백준
- 티스토리챌린지
- 운영 체제
- 컴퓨터 구조
Archives
- Today
- Total
감자는 아직 꿈을 꾼다.
[백준-JAVA] 1717번 집합의 표현 본문
알고리즘 : 유니온 파인드
유니온 파인드는 말그대로 합치기와 탐색입니다.
여기서 상호 배타적인 집합 관계가 나옵니다. 말 그대로 둘이 어떠한 교집합도 없는 집합입니다.
그래프로 생각하면 둘이 완전히 분리된 그래프 인거죠.
파인드는 자기 자신의 부모로 계속 올라가서 루트 노드까지 가는 과정이고
여기에서 만약 서로 다른 두 점을 파인드 했는데 루트 노드가 같을 경우는 이미 같은 집합 인것이고
다를 경우는 다른 집합인 것이겠죠
유니온은 말 그대로 두 집합을 합치는 과정인데 여기서 중요한 게 깊이 차이를 신경써야됩니다.
그냥 막무가내로 붙여버리면 깊이가 깊어져서 비효율적이게 됩니다.
그래서 두 루트노드의 랭크를 확인해서 더 큰 랭크인 루트노드를 부모 루트 향하게 작은 랭크의 루트노드를 바꿔주면 트리의 깊이 차가 안생기므로 효율적인 방법이죠.
이러한 유니온 파인드를 구현만 한 문제가 1717번입니다.
문제설명
링크참조
https://www.acmicpc.net/problem/1717
import java.io.*;
import java.util.*;
class Main{
private static StringBuilder sb;
// union 둘의 루트 노드의 랭크를 비교
// 큰 루트 존재시 : 작은 루트의 부모를 큰 루트 노드로 바꾸고,큰 루트노드 랭크 +1
// 동일 할 시: 아무쪽으로 붙이고 랭크 +1
private static void union(int[] arr,int[] rank, int a,int b) {
int aRoot = find(arr,a);
int bRoot = find(arr,b);
if (aRoot == bRoot) {
return;
}else {
if (rank[aRoot] >= rank[bRoot]) {
rank[aRoot]++;
arr[bRoot] = aRoot;
}else {
rank[bRoot]++;
arr[aRoot] = bRoot ;
}
}
}
// Find : 같은 집합에 포함되어 있는 지 확인하려면 루트 노드가 같은 지 확인
private static int find(int[] arr ,int a) {
while(arr[a] != a) {
a = arr[a];
}
return a;
}
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[] arr = new int[N+1];
int[] rank = new int[N+1];
sb = new StringBuilder();
// 초기 상태는 전부 자기 자신이 루트
for (int i = 0; i <= N; i++) {
arr[i] = i;
}
for (int i= 0; i< M;i++) {
st = new StringTokenizer(br.readLine());
int mode = Integer.parseInt(st.nextToken());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
if (mode == 0) {
union(arr,rank,a,b);
}else {
if (find(arr,a) == find(arr,b)) sb.append("YES\n");
else sb.append("NO\n");
}
}
System.out.println(sb);
}
}
'코테적 감자 > 백준' 카테고리의 다른 글
[백준-java] 토마토 7576번 7569번 (0) | 2024.11.19 |
---|---|
[백준-java] 3613번 실버 3 java vs c++ (0) | 2024.11.17 |
[백준-java] 9996번 실버 3 한국이 그리울 땐 서버에 접속하지 (1) | 2024.11.16 |
[SWEA-java] 미생물 격리 (2) | 2024.11.15 |
[백준-java] 골드 4 타임머신 (2) | 2024.11.09 |