이분 그래프를 구현하는 문제였다.
우선 이분 그래프가 무엇인지 이해해야 한다.
참고 블로그 (이해를 위한 설명과 사진 참조)
https://www.ksakosmos.com/post/%EA%B7%B8%EB%9E%98%ED%94%84-%EC%9D%B4%EB%A1%A0-%EB%A7%9B%EB%B3%B4%EA%B8%B0-%EC%9D%B4%EB%B6%84-%EA%B7%B8%EB%9E%98%ED%94%84
이 처럼 2 집합으로 나눠서 각 집합에 속한 정점끼리는 인접되지 않는, 즉 간선이 직접 연결되서는 안된다.
정리하자면
삽입과 삭제가 많다면 ArrayList는 비효율적이다.
LinkedList는 순차적 접근이기 때문에 검색의 속도가 느리다.
그래서 LinkedList로 구현해버리면 시간초과 오류가 났다... 이런 사소한 점을 꼭 기억하자.!!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static List<List<Integer>> graph;
static int[] colors;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int k = Integer.parseInt(br.readLine());
for(int i=0;i<k;i++){
st = new StringTokenizer(br.readLine()," ");
int v = Integer.parseInt(st.nextToken());
int e = Integer.parseInt(st.nextToken());
//초기화
colors = new int[v+1];
graph = new ArrayList<>();
for(int j=0;j<=v;j++){
graph.add(new ArrayList<>());
}
//그래프 설정
for(int j=0;j<e;j++){
st = new StringTokenizer(br.readLine()," ");
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
graph.get(from).add(to);
graph.get(to).add(from);
}
boolean check = false;
//모든 정점을 방문
for(int vertex=1;vertex<=v;vertex++){
if(colors[vertex] == 0){
check = BFS(vertex, 1);
}
if(!check){
break;
}
}
if(check) System.out.println("YES");
else System.out.println("NO");
}
}
private static boolean BFS(int start, int color) {
Queue<Integer> queue = new LinkedList<>();
queue.add(start);
//시작 정점 색칠
colors[start] = color;
while(!queue.isEmpty()) {
int cur = queue.remove();
for (int next : graph.get(cur)) {
//인접 정점 색이 동일하면 이분 그래프가 아님
if (colors[cur] == colors[next]) {
return false;
}
//현재 정점의 반대 색깔로 색칠
if(colors[next] == 0){
colors[next] = colors[cur] * -1;
queue.add(next);
}
}
}
return true;
}
}