[BOJ] 1707. 이분그래프 (Java)

Problem

제출일 : 2020-02-27

문제 풀이 시간 : 30M

난이도 : ★☆


link : https://www.acmicpc.net/problem/1707

그래프의 정점의 집합을 둘로 분할하여, 각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있을 때, 그러한 그래프를 특별히 이분 그래프 (Bipartite Graph) 라 부른다.

그래프가 입력으로 주어졌을 때, 이 그래프가 이분 그래프인지 아닌지 판별하는 프로그램을 작성하시오.

input

입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수 E(1≤E≤200,000)가 빈 칸을 사이에 두고 순서대로 주어진다. 각 정점에는 1부터 V까지 차례로 번호가 붙어 있다. 이어서 둘째 줄부터 E개의 줄에 걸쳐 간선에 대한 정보가 주어지는데, 각 줄에 인접한 두 정점의 번호가 빈 칸을 사이에 두고 주어진다.

Output

K개의 줄에 걸쳐 입력으로 주어진 그래프가 이분 그래프이면 YES, 아니면 NO를 순서대로 출력한다.

Example

input

2
3 2
1 3
2 3
4 4
1 2
2 3
3 4
4 2

output

YES
NO

Solution & Inpression

주어진 그래프가 이분 그래프인지 확인하는 방법은 각 정점들을 BFS나 DFS를 이용하여 정점을 탐색해나아가며 색을 칠하며 같은 색의 꼭짓점이 서로 연결되어 있는 모순이 발생하는지 여부를 확인하면 된다.

문제를 풀때 주의 해야할 점은 1번 정점만을 탐색한다해서 모든 정점을 순회할 수 없는 테스트케이스가 있기 때문에 모든 정점을 탐색할 수 있도록 구현해야한다.

Code

언어 : JAVA

메모리 : 314196 kb

실행시간 : 2804 ms

import java.io.FileInputStream;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws Exception {
        System.setIn(new FileInputStream("res/input.txt"));
        Scanner sc = new Scanner(System.in);
        int K = sc.nextInt();
        for (int tc = 0; tc < K; tc++) {
            int V = sc.nextInt();
            int E = sc.nextInt();

            LinkedList<Integer>[] graph = new LinkedList[V];
            for (int i = 0; i < V; i++) {
                graph[i] = new LinkedList<>();
            }
            for (int i = 0; i < E; i++) {
                int s = sc.nextInt() - 1;
                int e = sc.nextInt() - 1;
                graph[s].add(e);
                graph[e].add(s);
            }

            boolean flag = true;
            int[] visit = new int[V];
            Queue<Integer> q = new LinkedList<>();

            for (int i = 0; i < V; i++) {
                if (visit[i] == 0) {
                    q.offer(i);
                    visit[i] = 1;

                    while (!q.isEmpty() && flag) {
                        int cur = q.poll();
                        for (Integer next : graph[cur]) {
                            if (visit[next] == 0) {
                                q.offer(next);
                                visit[next] = visit[cur] * -1;
                            } else if (visit[next] == visit[cur]) {
                                flag = false;
                                break;
                            }
                        }
                    }

                }
            }
            if (flag)
                System.out.println("YES");
            else
                System.out.println("NO");
        }
    }
}