[λ°±μ€ / JAVA] 1717λ², μ§ν©μ νν (Union-Find)
λ¬Έμ
μ΄κΈ°μ n+1$n+1$κ°μ μ§ν© {0}, {1}, {2},…, {n} μ΄ μλ€. μ¬κΈ°μ ν©μ§ν© μ°μ°κ³Ό, λ μμκ° κ°μ μ§ν©μ ν¬ν¨λμ΄ μλμ§λ₯Ό νμΈνλ μ°μ°μ μννλ €κ³ νλ€.
μ§ν©μ νννλ νλ‘κ·Έλ¨μ μμ±νμμ€.
μ λ ₯
첫째 μ€μ n, mμ΄ μ£Όμ΄μ§λ€. mμ μ λ ₯μΌλ‘ μ£Όμ΄μ§λ μ°μ°μ κ°μμ΄λ€. λ€μ mκ°μ μ€μλ κ°κ°μ μ°μ°μ΄ μ£Όμ΄μ§λ€. ν©μ§ν©μ 0 a bμ ννλ‘ μ λ ₯μ΄ μ£Όμ΄μ§λ€. μ΄λ aκ° ν¬ν¨λμ΄ μλ μ§ν©κ³Ό, bκ° ν¬ν¨λμ΄ μλ μ§ν©μ ν©μΉλ€λ μλ―Έμ΄λ€. λ μμκ° κ°μ μ§ν©μ ν¬ν¨λμ΄ μλμ§λ₯Ό νμΈνλ μ°μ°μ 1 a bμ ννλ‘ μ λ ₯μ΄ μ£Όμ΄μ§λ€. μ΄λ aμ bκ° κ°μ μ§ν©μ ν¬ν¨λμ΄ μλμ§λ₯Ό νμΈνλ μ°μ°μ΄λ€.
μΆλ ₯
1λ‘ μμνλ μ λ ₯μ λν΄μ aμ bκ° κ°μ μ§ν©μ ν¬ν¨λμ΄ μμΌλ©΄ "YES" λλ "yes"λ₯Ό, κ·Έλ μ§ μλ€λ©΄ "NO" λλ "no"λ₯Ό ν μ€μ νλμ© μΆλ ₯νλ€.
νμ΄
μ λμ¨ νμΈλμ λν΄ μκ³ μλ€λ©΄ λΉ λ₯΄κ² νμ μλ λ¬Έμ μ
λλ€. (λ¬Όλ‘ λλ μ΄κ±Έ νλ©΄μ μκ² λμμ§λ§)
λΆλͺ¨ λ Έλλ₯Ό λ§λ€μ΄ λκ³ κ° λΆλͺ¨κ° μ΄λ€ λ ΈλμΈμ§ μ€μ ν΄ μ£Όλ μμ μ΄λΌκ³ μκ°νλ©΄ λ©λλ€.
μ²μ Parents[i]λ i(λ³ΈμΈ)μ μ€μ ν μνμ λλ€.
κ·Έλ¦¬κ³ 0μ λ°μΌλ©΄ λ λ Έλλ₯Ό union(ν©μ§ν©) ν©λλ€. μ λ μμ nodeλ₯Ό λΆλͺ¨λ‘ μ€μ νλ μμ μ νμμ΅λλ€.
λ§μ§λ§μΌλ‘, 1μ λ°κ²λλ©΄ λ λ Έλκ° κ°μ λΆλͺ¨λ₯Ό κ°κ³ μλμ§ connected()λ₯Ό ν΅ν΄ νμΈνμ¬ Yesμ Noλ₯Ό λ°ννλ μμ μ νκ² λ©λλ€.
ν΄λΉ μμ€ μ½λμ λλ€.
import java.io.*;
import java.util.*;
/**
* λ¬Έμ : 1717_μ§ν©μνν
* μ΄κΈ°μ $n+1$κ°μ μ§ν© $\\{0\\}, \\{1\\}, \\{2\\}, \\dots , \\{n\\}$μ΄ μλ€. μ¬κΈ°μ ν©μ§ν© μ°μ°κ³Ό,
* λ μμκ° κ°μ μ§ν©μ ν¬ν¨λμ΄ μλμ§λ₯Ό νμΈνλ μ°μ°μ μννλ €κ³ νλ€.
* μ§ν©μ νννλ νλ‘κ·Έλ¨μ μμ±νμμ€.
* μ
λ ₯ :
* 첫째 μ€μ $n$, $m$μ΄ μ£Όμ΄μ§λ€. $m$μ μ
λ ₯μΌλ‘ μ£Όμ΄μ§λ μ°μ°μ κ°μμ΄λ€.
* λ€μ $m$κ°μ μ€μλ κ°κ°μ μ°μ°μ΄ μ£Όμ΄μ§λ€.
* ν©μ§ν©μ $0$ $a$ $b$μ ννλ‘ μ
λ ₯μ΄ μ£Όμ΄μ§λ€.
* μ΄λ $a$κ° ν¬ν¨λμ΄ μλ μ§ν©κ³Ό, $b$κ° ν¬ν¨λμ΄ μλ μ§ν©μ ν©μΉλ€λ μλ―Έμ΄λ€.
* λ μμκ° κ°μ μ§ν©μ ν¬ν¨λμ΄ μλμ§λ₯Ό νμΈνλ μ°μ°μ $1$ $a$ $b$μ ννλ‘ μ
λ ₯μ΄ μ£Όμ΄μ§λ€.
* μ΄λ $a$μ $b$κ° κ°μ μ§ν©μ ν¬ν¨λμ΄ μλμ§λ₯Ό νμΈνλ μ°μ°μ΄λ€.
*/
public class Main {
static int[] parents;
public static void main(String[] args) throws Exception {
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());
parents = new int[n+1];
for (int i = 1; i <= n; i++) {
parents[i] = i;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int check = Integer.parseInt(st.nextToken());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
if (check == 0){
union(a,b);
}
else {
if (connected(a, b)){
sb.append("YES\\n");
}
else {
sb.append("NO\\n");
}
}
}
System.out.println(sb);
br.close();
}
static int find(int x) {
if (parents[x] != x) return parents[x] = find(parents[x]);
return parents[x];
}
static void union(int x, int y) {
int a = find(x);
int b = find(y);
if(a > b){
parents[b] = a;
}
else{
parents[a] = b;
}
}
static boolean connected(int a, int b) {
return find(a) == find(b);
}
}