상세 컨텐츠

본문 제목

1707. 이분 그래프

Algorithm

by aeongiii 2025. 1. 24. 01:36

본문

 

1. 문제 분석
    1) 테스트케이스 T에 대해, 첫째 줄에 V E 가 주어지고 둘째줄부터 E개 줄에 걸쳐 u v가 주어짐
    2) 여러개의 테스트케이스가 있다.
    3) 해당 그래프가 이분 그래프이면 YES, 아니면 NO를 출력한다.
    4) 이분그래프인지 아는 법
        - 이분그래프 : 그래프의 모든 정점이 두 그룹으로 나눠지고, 서로 다른 그룹의 정점이 연결되어있음
            = 인접한 정점끼리 칠하면 서로 다른색으로 칠해져야 함
            = 인접한 정점끼리 나누면 딱 두개로 나눠져야 함
            = 빨간색은 파란색이랑만 인접해야 하고.. 파랑은 빨강이랑만 인접해야 한다.
        - BFS, DFS를 사용해서 구할 수 있다.
            - 정점을 방문할 때마다 A 또는 B로 칠한다.
            - 다음 정점(인접)을 방문할 때는 자신과 다른 색으로 칠한다.
            - 탐색을 진행하다가,, 다음 정점(인접)이 자신과 같은 색이라면 바로 컷
            - BFS의 경우 같은 레벨에서 정점을 다른 색으로 칠해야 한다면 바로 컷
            * 근데 만약 비연결그래프라면 !! 모든 정점에 대해 확인해야 한다.

2. 제약 조건
    1) 2 <= K <= 5
    2) 1 <= V <= 20000
    3) 1 <= E <= 200000

3. 의사결정
    1) T를 입력받아서 while문 돌리기
    2) 첫줄에서 V E를 입력받고, V*V인 인접리스트 만들기
    3) E개의 줄을 입력받으면서 u v 입력받아서 (u, v)에 저장하기
    4) bfs 큐 사용해보기 ! 방문할때 색깔 확인하는 작업 진행해줘야 한다.
    5) 비연결 그래프일 경우... 어차피 이중배열 싹 돌면서 확인해야하나??


4. 문제풀이
    1) V가 최대 20000이라서 이중 배열을 쓰면 메모리 초과 가능성
    2) 빨강 1, 파랑 -1, 미방문 0

 

import java.io.*;
import java.util.*;

public class Main {

    static int T;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        T = Integer.parseInt(br.readLine());

        // 테스트케이스
        while(T-- > 0) {

            StringTokenizer st1 = new StringTokenizer(br.readLine());
            int V = Integer.parseInt(st1.nextToken());
            int E = Integer.parseInt(st1.nextToken());

            // 인접리스트 만들기
            ArrayList<Integer>[] graph = new ArrayList[V+1];
            for (int i = 1; i <= V; i++) {
                graph[i] = new ArrayList<>(); // 초기화
            }
            
            // 간선 연결정보 입력받기기
            for (int i = 0; i < E; i++) {
                StringTokenizer st2 = new StringTokenizer(br.readLine());
                int u = Integer.parseInt(st2.nextToken());
                int v = Integer.parseInt(st2.nextToken());
                graph[u].add(v);
                graph[v].add(u);
            }

            // 방문 정보 입력할 visited 추가
            int[] color = new int[V+1];

            // 정답 TF 체크할 변수
            boolean result = true;

            // 비연결 그래프 있을 수도 있기 때문에 전체 돌면서..
            for (int i = 1; i <= V; i++) {
                if (color[i] == 0) {
                    if (!bfs(i, graph, color)) { // false 반환하면 이분그래프 아님
                        result = false;
                        break;
                    }
                }
            }
            System.out.println(result ? "YES" : "NO");
        }
    }

    private static boolean bfs(int start, ArrayList<Integer>[] graph, int[] color) {

        Queue<Integer> queue = new LinkedList<>();
        queue.add(start);
        color[start] = 1; // 색깔 = 1

        while(!queue.isEmpty()) {
            int now = queue.poll();

            for (int next : graph[now]) { // 같은 라인 다 돌면서

                if (color[next] == 0) {
                    if (color[now] == 1) { // 반대로 칠하기
                        color[next] = -1;
                    } else { // 반대로 칠하기
                        color[next] = 1;
                    }
                    queue.add(next);
                } 
                
                else if (color[next] == color[now]) {
                    // 같은 색 발견시 이분그래프 ㄴㄴ
                    return false;
                }

            }
        }
        return true; // 제대로 끝났다면 이분그래프 ㅇㅇㅇ
    }
}

 

 

풀긴 풀었는데 풀이과정이 너무 꼬였어서 정리가 안되는 느낌,, 내일 다시 풀어봐야겠다...~~~

'Algorithm' 카테고리의 다른 글

1920. 수 찾기  (0) 2025.02.06
1018. 체스판 다시 칠하기  (0) 2025.02.04
2667. 단지 번호 붙이기  (1) 2025.01.23
1260. DFS와 BFS  (0) 2025.01.20
2470. 두 용액  (1) 2025.01.17

관련글 더보기