본문 바로가기

Algorithm

백준 9466 텀 프로젝트 Java

정답률 24퍼센트의 어려운 그래프 문제이다. '팀'프로젝트 인줄 알았는데

'텀'프로젝트였다. 이유는 모르겠다.

학생끼리 조를 짤 때 하고싶은 사람이 꼭 겹쳐야 조를 짤 수 있다.

한마디로 싸이클인 그래프에 속한 학생들만 조를 짤 수 있다는 것이다.

 

혼자하고 싶은 학생들은 자기 자신을 가리켜도 된다.

또는 마지막 학생이 가리킨 학생이 반드시 시작한 학생이여야 한다.

 

방문했는지를 확인하는 boolean형 배열 대신

int형 배열로 현재 정점이 몇 번째 방문한 정점인지 저장하고

또다른 int형 배열로 현재 정점이 어디서 부터 시작된 정점인 건지를 체크하고

확인하는 방식으로 문제를 풀면 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
import java.util.Scanner;
 
public class Q9466 {
    static int a[]; //입력받는 배열
    static int check[]; //방문 check(시작에서부터 몇번째로 방문되는 것인지)
    static int startVertex[];   //시작정점
     
    static int dfs(int i, int cnt, int start){
        
        if(check[i]!=0){ //이미 방문했던 정점이라면
            if(start!=startVertex[i]) //시작 정점과 같지 않은지 확인
                return 0;               //같지않다면 0리턴
            return cnt-check[i]; //같으면 몇번째 방문한 정점인지 리턴..
        }
         
        check[i]=cnt; //몇번째 방문한건지 저장 
        startVertex[i]=start; 
        return dfs(a[i],cnt+1, start); //가리키는 정점, +1번째 방문, start그대로 
    }
     
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int t=sc.nextInt();
         
        while(t-- > 0)
        {
            int n=sc.nextInt();
            a=new int[n+1];
            check=new int[n+1];
            startVertex=new int[n+1];
             
            for(int i=1;i<=n;i++)
                a[i]=sc.nextInt();
             
            int ans=0;
            for(int i=1;i<=n;i++){
                if(check[i]==0)
                    ans+=dfs(i,1,i);
            }
            System.out.println(n-ans);
         
        }
    }
}
 

예제에 있는 3 1 3 7 3 4 6 으로 설명해보자.

3은 자기 자신을 가리키기 때문에 생략하고

4 ->7 ->6 ->4 

4인경우

check[4] = 1

startVertex[4] = 1

4가 7을 가리키기 때문에 -> dfs(7, 2, 4)

check[7] = 2

startVertex[7] = 4

7이 6을 가리키기 때문에 ->dfs(6, 3, 4)

check[6] = 3

startVertex[6] = 4

6은 4를 가리키기 때문에 -> dfs(4, 4, 4)

이 때 if(check[i]!=0){ //이미 방문했던 정점이라면

            if(start!=startVertex[i]) //시작 정점과 같지 않은지 확인

                return 0;               //같지않다면 0리턴

            return cnt-check[i]; //같으면 몇번째 방문한 정점인지 리턴..

        }

조건문에 걸리게 된다.

cnt = 4 , check[4] = 1

4-1 = 3이므로 3명의 조원이 있는 것이다.

 

정답률이 낮은만큼 구현하는것도 그렇고 이해하기 조차 힘든 문제인 것 같다.

'Algorithm' 카테고리의 다른 글

백준 1167 트리의지름 Java  (0) 2019.04.29
백준 2146 다리만들기 Java  (0) 2019.04.24
백준 1377 버블 소트 Java  (0) 2019.04.19
백준 6588 골드바흐의 추측 Java  (0) 2019.04.17
백준 1929 소수 구하기 Java  (0) 2019.04.17