https://www.acmicpc.net/problem/1976
1976번: 여행 가자
동혁이는 친구들과 함께 여행을 가려고 한다. 한국에는 도시가 N개 있고 임의의 두 도시 사이에 길이 있을 수도, 없을 수도 있다. 동혁이의 여행 일정이 주어졌을 때, 이 여행 경로가 가능한 것인
www.acmicpc.net
코드설명
유니온 파인드(Union Find) 문제입니다.
각 정점들이 같은 그래프내에 있는지만 확인하면 되기에 유니온 파인드를 활용하여 해당 그래프들이 같은 그룹에 있는지 확인합니다.
유의해야하는점은
//int ParentValue = parent[plan[0] - 1]; int ParentValue = findParent(plan[0] - 1);   for(int i=1;i<M;i++) { //if(ParentValue != parent[plan[i] - 1]) {     if(ParentValue != findParent(plan[i] - 1)) {         System.out.println("NO");         return ;     } } 
- Parent[] 를 통해 접근하면 정답이 아니고, findParent를 통해 접근해야만 올바르게 통과합니다.
 - 물론, findParent를 통해서 Parent값을 갱신하며 진행할 수 있지만, 왜 Parent로 접근하여 비교한다면 올바른 정답이 아닌것인가라는 의문이 생깁니다. Parent[i] 로 접근하나, findParent[i]로 접근하나 결과값은 동일하다고 생각할 수 있습니다.
 - 하지만, 만약 더 낮은 Index의 값이 나중에 들어왔다고 할경우 이전에 unionParent한 값의 parent배열은 변경되지 않으므로 새롭게 findParent를 통해 parent를 갱신시켜야합니다.
 
또한 추가로, 시간을 더 감소시키기 위해서
for(int i=1; i<=N;i++) {     st = new StringTokenizer(br.readLine());     for(int j=1; j<=i;j++) {         arr[i][j] = Integer.parseInt(st.nextToken());         if(arr[i][j] == 1) {             unionParent(i, j);         }     } } 
입력으로 주어진 도시의 연결정보에서 대각선 기준으로 대칭모양이므로 위와 같이 j<=i 로만 처리하여 중복결과를 피할 수 있습니다.
0 1 0 1 0 1 0 1 0 
정답을 구할때는 처음에 주어진 여행게획을 Parent Value로 입력받고, 그 이후에 여행계획들이 Parent Value와 다르다면 같이 분리집합이 아니므로 실패처리합니다.
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*;   public class Main { 	public static int N, M; 	public static int answer = 0; 	public static int[][] arr; 	public static int[] parent;     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());     	     	st = new StringTokenizer(br.readLine());     	M = Integer.parseInt(st.nextToken());     	     	arr = new int[N+1][N+1];     	parent = new int[N+1];     	for(int i=1;i<=N;i++) {     		parent[i] = i;     	}     	     	for(int i=1; i<=N;i++) {     		st = new StringTokenizer(br.readLine());     		for(int j=1; j<=i;j++) {     			arr[i][j] = Integer.parseInt(st.nextToken());     			if(arr[i][j] == 1) {     				unionParent(i, j);     			} 			}     	}     	     	     	for(int i=1; i<=N;i++) {     		findParent(i);     	}     	     	st = new StringTokenizer(br.readLine());     	int storeParent = parent[Integer.parseInt(st.nextToken())];     	for(int i=2;i<=M;i++) {     		if(storeParent != parent[Integer.parseInt(st.nextToken())]) {     			System.out.println("NO");     			return ;     		}     	}     	System.out.println("YES");     	 	}          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) {     		parent[b] = a;     	}else {     		parent[a] = b;     	}     }           } 
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*;   public class Main { 	public static int N, M; 	public static int[][] arr; 	public static int[] plan; 	 	public static int[] parent = new int[201]; 	 	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 ) parent[b] = a; 		else parent[a] = b; 	} 	     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());     	st = new StringTokenizer(br.readLine());     	M = Integer.parseInt(st.nextToken());     	     	arr = new int[N][N]; //    	parent = new int[N];     	     	for(int i=0;i<N;i++) {     		parent[i] = i;     	}     	 //    	for(int i=0;i<N;i++) { //    		System.out.print(" "+parent[i]); //    	}     	for(int i=0;i<N;i++) {     		st = new StringTokenizer(br.readLine());     		for(int j=0;j<N;j++) {     			arr[i][j] = Integer.parseInt(st.nextToken());     		}     	}     	     	for(int i=0;i<N;i++) {     		     		for(int j=0;j<=i;j++) {     			     			if(arr[i][j] == 1) {     				unionParent(i, j);	     			}     			     		}     	}     	     	st = new StringTokenizer(br.readLine());     	plan = new int[M];     	     	for(int i=0;i<M;i++) {     		plan[i] = Integer.parseInt(st.nextToken());     	}     	if( M < 0) System.out.println("YES");     	 //    	int ParentValue = parent[plan[0] - 1];     	int ParentValue = findParent(plan[0] - 1); // //만약 더 낮은 Index의 값이 나중에 들어왔다고 할경우 이전에 unionParent한 값의 parent배열은 변경되지 않으므로 새롭게 findParent를 통해 parent를 갱신시켜야합니다.     	      	for(int i=1;i<M;i++) { //    		if(ParentValue != parent[plan[i] - 1]) {     		if(ParentValue != findParent(plan[i] - 1)) { // //만약 더 낮은 Index의 값이 나중에 들어왔다고 할경우 이전에 unionParent한 값의 parent배열은 변경되지 않으므로 새롭게 findParent를 통해 parent를 갱신시켜야합니다.     			System.out.println("NO");     			return ;     		}     	}     	System.out.println("YES");     } } 
'알고리즘 > Disjoint Set' 카테고리의 다른 글
| [백준] 4195 친구 네트워크 - 유니온파인드(Union Find) + 해쉬맵(HashMap) JAVA (0) | 2023.09.05 | 
|---|---|
| [백준] 16562 친구비 - 유니온파인드(Union Find) + 최소조건(Minimum) JAVA (0) | 2023.09.05 | 
| [백준] 1717 집합의 표현 - 유니온파인드(Union Find) JAVA (0) | 2023.09.05 | 
| [백준] 1043 거짓말 - 유니온파인드(Union Find) JAVA (0) | 2023.08.27 | 
| [백준] 3197 백조의 호수 - BFS(너비우선탐색) + 유니온파인드(Union Find) JAVA (0) | 2023.08.25 |