https://www.acmicpc.net/problem/20040
20040번: 사이클 게임
사이클 게임은 두 명의 플레이어가 차례대로 돌아가며 진행하는 게임으로, 선 플레이어가 홀수 번째 차례를, 후 플레이어가 짝수 번째 차례를 진행한다. 게임 시작 시 0 부터 n − 1 까지 고유한
www.acmicpc.net
코드설명
트리(Tree) + 분리집합(disjoint set) + 유니온파인드(Union Find) 문제입니다.
처음에는 DFS를 활용하여 진행하려했습니다.
만약에 노드의 정점이 첫 시작이 반드시 0 으로 시작했다면, DFS를 통해서도 진행할 수 있었겠지만, 그렇지 않기에 DFS로 진행하지 못합니다. 만약, DFS를 사용하려면, hashset으로 현재까지 나온 Index값을 가지고서 해당 값들을 DFS를 통해 해결할 수 있겠지만 비효율적을 보이기에 유니온파인드를 통해 만약 새로 들어온 값이 findParent를 하였을때 같은 값으로 맞추어진다면 싸이클이 발생한것으로 해당 작업의 순서를 출력시키고 중단시키면됩니다.
처음에 사용해보려던 DFS코드입니다.
// 언제 싸이클이 발생되었는지 시점을 알기 위해 DFS를 사용하지 못한다. DFS를 사용하려면, hashset으로 현재까지 나온 Index값을 가지고서 해당 값들을 DFS를 통해 해결할 수 있겠지만 비효율적으로 보인다. public static boolean dfs(int parent, int child) { for(int i=0;i<graph.get(child).size();i++) { int now = graph.get(child).get(i); if(parent == now) continue; if(visited[now] == true) return false; visited[now] = true; if(dfs(child, now) == false) return false; } return true; }
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.StringTokenizer; public class Main { public static int N, M, H; public static int answer = 0; public static int[] arr; public static boolean[] visited; public static int[] parent; public static ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>(); public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); visited = new boolean[N]; parent = new int[N]; for(int i=0;i<N;i++) { parent[i] = i; } for(int i=0;i<N;i++) { graph.add(new ArrayList<Integer>()); } for(int i=0;i<M;i++) { st = new StringTokenizer(br.readLine()); int a = Integer.parseInt(st.nextToken()); int b = Integer.parseInt(st.nextToken()); if(findParent(a) == findParent(b)) { System.out.println( (i+1) ); return ; } else if(findParent(a) != findParent(b)) { unionParent(a, b); } } System.out.println(0); } public static int findParent(int x) { if( x == parent[x]) return x; return parent[x] = findParent(parent[x]); } public static void unionParent(int a, int b) { a = findParent(a); b = findParent(b); if( a == b) visited[a] = true; //싸이클이 발생한 시점이다. if( a < b) parent[b] = a; else parent[a] = b; } }