꾸물꾸물 졔의 개발공부

[백준] 13023 ABCDE - JAVA 본문

알고리즘/백준

[백준] 13023 ABCDE - JAVA

체제 2023. 8. 11. 14:56

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

 

13023번: ABCDE

문제의 조건에 맞는 A, B, C, D, E가 존재하면 1을 없으면 0을 출력한다.

www.acmicpc.net

 

⏰ 친구관계를 행렬로 구현했더니 시간초과가 났다. > 인접리스트로 

 

 

알고리즘

  • 최소 4개의 친구관계(A→B→C→D→E)가 연결되어 있는지 확인하기 위해 깊이우선탐색인 DFS로 구현 
  • 백트래킹
  • 주어진 친구관계는 인접리스트로 구현 ( 인접행렬시 시간초과
  • 사람의 수가 5명보다 많더라도, 만족하는 친구관계는 주어진 4개만 만족하면 된다. (=DFS에서 탐색 깊이가 4이상이면 친구 관계 존재

 

구현 과정

  • ArrayList<List<Integer>> list : 주어진 친구관계를 저장하기 위한 인접리스트 
  • checked[] : DFS 탐색에서 각 사람이 현재 탐색중인 친구 관계에 포함되어있는지 확인하기 위한 boolean 형 배열
  • dfs(int i, int cnt) : i와 친구인 다음 사람으로 깊이우선탐색, 몇번 째 친구 관계 탐색인지 확인하기 위한 cnt 변수 

 

1. 주어진 M개의 친구관계를 인접리스트에 양방향으로 저장한다. (0 1 이라면 0의 친구 1 = 1의 친구 0)

 

2. N명의 사람에 대해 DFS 탐색을 반복한다. (0 i < N) 인 i부터 시작하여 DFS 탐색을 시작했을 때 친구 관계가 존재하는지 확인  

 

3. DFS , 깊이우선탐색 과정은 다음과 같다. 매개변수 ▶  i: i의 친구 찾는 중, cnt : 몇번 째 연결된 관계인지

  • 종료조건 : cnt 가 4라면 result 를 1로 하여 리턴한다.
    A→B→C→D→E 의 친구관계를 만족하려면 탐색 관계가 4번 이루어져야 한다. cnt 가 4라는 것은 4명 이상이 연결되어 있다는 뜻 (= 친구 관계 존재) 
  • i의 친구 중, 아직 친구 관계에 포함되지 않은 (checked가 false) 친구를 찾아 checked, dfs 
  • 백트래킹 구현을 위해 아래에 'checked = false' 코드를 추가한다. (return시, false) 

 

 

4. 만약 result가 1이 되었을 경우 2번 과정의 반복을 종료한다. 

 

5. 최종적으로 result를 출력. 

 


 

소스 코드

import java.util.*;
import java.io.*;
	
public class Main {
	static boolean checked[] ; 
	static ArrayList<List<Integer>> list = new ArrayList<>() ; 
	static int N; 
	static int result; //결과: 친구관계 존재 1, 존재x 0
    
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
		StringTokenizer st; 
		
		st= new StringTokenizer(br.readLine(), " ");
		N = Integer.parseInt(st.nextToken()); //사람의 수 
		for(int i=0; i<N; i++) list.add(new ArrayList<>()); 
        
		int M = Integer.parseInt(st.nextToken()); //관계의 수 
		while(M-- >0) {
			st = new StringTokenizer(br.readLine(), " ");
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			
			list.get(a).add(b);
			list.get(b).add(a);
		}
		
		for(int i=0; i<N; i++) {			
			checked= new boolean[N]; 
			checked[i] = true; 
			dfs(i,0); //i를 처음 시작점으로 두어 친구관계 성립하는지 확인 
			
			//존재하면 더이상 탐색할 필요 x
			if(result == 1) break; 

		}
		
		System.out.println(result);
	}//end of main 
	
	private static void dfs(int i, int cnt) {		
		if(cnt == 4) {
			result = 1;
			return; 
		}
		
		for(int j : list.get(i)) {
			if(!checked[j]) {
				checked[j] = true; 
				dfs(j, cnt+1);
				checked[j] = false; //백트래킹
			}
		}
	}
}//end of class

 

 

 

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 1520 내리막 길 - JAVA  (0) 2023.08.15
[백준] 9935 문자열 폭발 - JAVA  (0) 2023.08.14
[백준] 2589 보물섬 - JAVA  (0) 2023.08.10
[백준] N과 M(5~8) 순열 - JAVA  (0) 2023.07.17
[백준] N과 M(1~4) 순열 - JAVA  (0) 2023.07.16