Algorithm

[BOJ_1976] μ—¬ν–‰κ°€μž (κ³¨λ“œ4) - JAVA

이수밈 2023. 12. 12. 15:57


🐾 μ•Œκ³ λ¦¬μ¦˜

  • Union - Find : μ„œλ‘œμ†Œ 집합을 μ΄μš©ν•΄μ„œ ν’€κΈ°!
  • 이 외에도 bfs, ν”Œλ‘œμ΄λ“œ-μ›Œμƒ¬ μ•Œκ³ λ¦¬μ¦˜μ„ ν™œμš©ν•΄ 풀이 κ°€λŠ₯

 


🐾 생각 포인트

  • 6λ²ˆμ •λ„ λ©”λͺ¨λ¦¬μ΄ˆκ³Όμ™€ λŸ°νƒ€μž„μ—λŸ¬κ°€ λ‚¬λŠ”λ°, 였λ₯˜λ₯Ό μˆ˜μ •ν•˜λŠλΌ ν•œμ°Έ κ³ λ―Όν–ˆλ‹€.  였λ₯˜κ°€ λ‚œ 곳은 λ‹€λ¦„μ•„λ‹Œ union method, μ—¬κΈ°μ„œ find(x)λ₯Ό x둜 μ •μ˜ν•˜κ³  find(y)λ₯Ό y둜 μž¬μ •μ˜ν•œ 것이 λ¬Έμ œμ˜€λ‹€. γ… γ…  κ·Έ 원인을 μ‰½κ²Œ 찾을 수 μ—†μ–΄ μ±—μ§€ν”Όν‹°μ—κ²Œ λ¬Όμ–΄λ³΄μ•˜λ‹€.
private static void union(int x, int y) {
//		x = find(x);
//		y = find(y);
//		
//		if (x > y)
//			parent[x] = y;
//		parent[y] = x;

직접 λΉ„κ΅ν•˜λ©΄ 잘λͺ»λœ κ²°κ³Όκ°€ λ‚˜μ˜¬ 수 μžˆλ‹€λŠ” 점,, μ΄λŠ” μœ λ‹ˆμ˜¨ νŒŒμΈλ“œ μ•Œκ³ λ¦¬μ¦˜μ‹œ ν”ν•œ μ‹€μˆ˜ 쀑 ν•˜λ‚˜λΌλŠ” 점,, λͺ…심 또 λͺ…심

 


경둜 μ••μΆ•(Path Compression)은 find ν•¨μˆ˜κ°€ 호좜될 λ•Œ ν•΄λ‹Ή λ…Έλ“œλΆ€ν„° λ£¨νŠΈκΉŒμ§€μ˜ 경둜 μƒμ˜ λͺ¨λ“  λ…Έλ“œμ˜ λΆ€λͺ¨λ₯Ό 직접 루트둜 λ§Œλ“€μ–΄μ£ΌλŠ” κΈ°μˆ μž…λ‹ˆλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ 같은 집합에 μ†ν•œ λ…Έλ“œλ“€μ΄ 더 짧은 경둜둜 λ£¨νŠΈμ— 도달할 수 있게 λ˜μ–΄, find ν•¨μˆ˜μ˜ 호좜 μ‹œκ°„μ„ 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ x = find(x);와 같이 직접 xλ₯Ό 루트둜 λ§Œλ“€λ©΄μ„œ ν• λ‹Ήν•˜κ²Œ 되면, find ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ μž¬κ·€ 호좜이 μ‚¬λΌμ§€κ²Œ λ©λ‹ˆλ‹€. μž¬κ·€ 호좜이 μ—†λ‹€λŠ” 것은 경둜 압좕을 μ μš©ν•˜μ§€ μ•Šμ•˜λ‹€λŠ” 것이며, μ΄λŠ” find ν•¨μˆ˜λ₯Ό μ—¬λŸ¬ 번 ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ 항상 λ£¨νŠΈμ— λ„λ‹¬ν•˜λŠ” 데 더 λ§Žμ€ μ‹œκ°„μ΄ μ†Œμš”λ  수 μžˆλ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.

By Chat GPT

5
5
0 1 0 0 0
1 0 0 0 1
0 0 0 1 0
0 0 1 0 1
0 1 0 1 0
3 5 4 2 1

ν•΄λ‹Ή λ°˜λ‘€μ—μ„œ λ¬΄ν•œμœΌλ‘œ λΉ™λΉ™ 돌며 μŠ€νƒμ˜€λ²„ν”Œλ‘œμš° ν˜„μƒ 확인



🐾 μ†ŒμŠ€μ½”λ“œ

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class Main_1976 {
	static int[] parent;
	static int N, M;
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st;
		N = Integer.parseInt(br.readLine()); // λ„μ‹œμ˜ 수
		M = Integer.parseInt(br.readLine()); // μ—¬ν–‰κ³„νšμ— μ†ν•œ λ„μ‹œλ“€μ˜ 수

		parent = new int[N + 1];
		for (int i = 1; i < N + 1; i++) {
			parent[i] = i;
		}

		for (int i = 1; i < N + 1; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 1; j < N + 1; j++) {
				int num = Integer.parseInt(st.nextToken());
				// 두 λ„μ‹œκ°€ μ—°κ²°λ˜μ–΄μžˆμœΌλ©΄, λΆ€λͺ¨λ₯Ό ν•˜λ‚˜λ‘œ ν†΅μΌμ‹œν‚€μž! (μœ λ‹ˆμ˜¨)
				if (num == 1)
					union(i, j);
			}
		}

		// μ—¬ν–‰κ³„νš
		st = new StringTokenizer(br.readLine());
		int start = Integer.parseInt(st.nextToken());
		for (int i = 1; i < M; i++) {
			int now = Integer.parseInt(st.nextToken());
			if (find(start) != find(now)) {
				// μ‹œμž‘μ κ³Ό κ·Έ ν›„κ°€ μ΄μ–΄μ Έμžˆμ§€ μ•ŠμœΌλ©΄ μ—¬ν–‰λΆˆκ°€λŠ₯
				bw.write("NO\n");
				bw.flush();
				bw.close();
				br.close();
				return;
			}
		}

		bw.write("YES\n");
		bw.flush();
		bw.close();
		br.close();
	}

	// μ΅œμƒμœ„ λΆ€λͺ¨(λŒ€ν‘œ)μ°ΎκΈ°
	private static int find(int x) {
		if (x != parent[x])
			 return parent[x] = find(parent[x]);
		return x;

	}

	// λ„μ‹œ μ—°κ²°ν•˜κΈ°
	private static void union(int x, int y) {
//		x = find(x);
//		y = find(y);
//		
//		if (x > y)
//			parent[x] = y;
//		parent[y] = x;
		int a = find(x);
		int b = find(y);

		if (a > b) {
			parent[a] = b;
		} else {
			parent[b] = a;
		}
	}
}

😡‍πŸ’« 곡뢀해야 ν•  점

  • μœ λ‹ˆμ˜¨νŒŒμΈλ“œ λ‹¨μˆœ μ•”κΈ°κ°€ μ•„λ‹Œ μ΄ν•΄ν•΄μ„œ 풀것... 
  • 자꾸 μ•”κΈ°λ‘œ 이어진닀... γ… γ…  원리λ₯Ό μ΄ν•΄ν•˜μž