정답률 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
|
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 |