BOJ에서 정답이 여러가지인 경우에는 스페셜 저지를 사용한다. 스페셜 저지는 유저가 출력한 답을 검증하는 코드를 통해서 정답 유무를 결정하는 방식이다. 오늘은 스페셜 저지 코드를 하나 만들어보려고 한다.
정점의 개수가 N이고, 정점에 1부터 N까지 번호가 매겨져있는 양방향 그래프가 있을 때, BFS 알고리즘은 다음과 같은 형태로 이루어져 있다.
2-2 단계에서 방문하지 않은 정점을 방문하는 순서는 중요하지 않다. 따라서, BFS의 결과는 여러가지가 나올 수 있다.
트리가 주어졌을 때, 올바른 BFS 방문 순서인지 구해보자.
첫째 줄에 정점의 수 N(2 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N-1개의 줄에는 트리의 간선 정보가 주어진다. 마지막 줄에는 BFS 방문 순서가 주어진다. BFS 방문 순서는 항상 N개의 정수로 이루어져 있으며, 1부터 N까지 자연수가 한 번씩 등장한다.
입력으로 주어진 BFS 방문 순서가 올바른 순서면 1, 아니면 0을 출력한다.
4
1 2
1 3
2 4
1 2 3 4
1
4
1 2
1 3
2 4
1 2 4 3
0
이 문제는 bfs(너비 우선 탐색) 알고리즘을 이용해서 풀 수 있었다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
static ArrayList<Integer>[] map; //인접 리스트
static Queue<Integer> path; //정해진 순서
static int N;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
map = new ArrayList[N+1];
for(int i=1; i<=N; i++) {
map[i] = new ArrayList<>();
}
for(int i=0; i<N-1; i++) {
String[] input = br.readLine().split(" ");
int start = Integer.parseInt(input[0]);
int end = Integer.parseInt(input[1]);
map[start].add(end);
map[end].add(start);
}
path = new LinkedList<>();
String[] input = br.readLine().split(" ");
for(int i=0; i<N; i++) {
path.add(Integer.parseInt(input[i]));
}
if(path.poll()!=1) { //1에서 시작하지 않는
System.out.println(0);
return;
}
if(bfs())
System.out.println(1);
else
System.out.println(0);
}
public static boolean bfs() {
Queue<Integer> queue = new LinkedList<>();
boolean[] visited = new boolean[N+1];
visited[1] = true;
queue.add(1);
while(!queue.isEmpty()) {
int temp = queue.poll();
HashSet<Integer> set = new HashSet<>();
for(int next : map[temp]) {
if(visited[next]) continue;
visited[next] = true;
set.add(next);
}
if(set.size()==0) continue;
for(int i=0; i<set.size(); i++) { //순서대로 갈수 있는 지 확인
int next = path.poll();
if(set.contains(next))
queue.add(next);
else
return false;
}
}
return true;
}
}