Algorism/백준

[백준] 20040번 : 사이클 게임 - JAVA [자바]

어린콩개발자 2024. 1. 5. 11:59

https://www.acmicpc.net/problem/20040

 

20040번: 사이클 게임

사이클 게임은 두 명의 플레이어가 차례대로 돌아가며 진행하는 게임으로, 선 플레이어가 홀수 번째 차례를, 후 플레이어가 짝수 번째 차례를 진행한다. 게임 시작 시 0 부터 n − 1 까지 고유한

www.acmicpc.net


문제

 

이 문제는 유니온파인드로 풀 수 있다.

문제가 요구하는 것은 간단하다. 그래프(집합)을 형성할때, 만약 사이클이 발생한다면, 그 차례의 수를 출력하는 것이다.

 

생각을 해보자 사이클은 언제 발생 될까?

 

두개의 점을 그래프를 연결하기전에 이미 두개의 점들의 대표자가 같다면 싸이클이다. - 그림을 그려보면 쉽게 알 수 있다.

아래는 실제로 풀면서 내가 그린 그림이다.

 

이점을 이용해서 유니온파인드 기본코드에서 위의 조건문만 추가해주면 쉽게 풀 수 있는 문제이다. 


전체 코드

public class Main {
    static int n, m;
    static int[] arr;
    
	public static void main(String[] args) throws Exception {
    	BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    	StringBuilder sb = new StringBuilder();
    	StringTokenizer st;
    	
    	st = new StringTokenizer(in.readLine());
    	
    	n = Integer.parseInt(st.nextToken());
    	m = Integer.parseInt(st.nextToken());
    	
    	arr = new int[n];
    	makeSet();
    	
    	int result = 0;
    	
    	for(int c = 0; c < m; c++) {
    		st = new StringTokenizer(in.readLine());
    		
    		int a = Integer.parseInt(st.nextToken());
    		int b = Integer.parseInt(st.nextToken());
    		
    		// 연결할 때 a의 부모와 b의 부모가 이미 같다면 이것은 사이클이다. 
    		if(findSet(a) == findSet(b)) {
    			result = c + 1;
    			break;
    		}
    		
    		union(a, b);
    	}
    	
    	System.out.println(result);
    	
    }
	static void makeSet() {
		for(int i = 0; i < n; i++) {
			arr[i] = i;
		}
	}
	
	static int findSet(int x) {
		if(x == arr[x]) {
			return x;
		}
		
		return arr[x] = findSet(arr[x]);
	}
	
	static void union(int x, int y) {
		if(x != y) {
			arr[findSet(y)] = findSet(x);
		}
	}
}

 


결과