[실전 문제] 2색 칠하기

2021. 2. 27. 17:28코딩 테스트/실전 문제

1. 문제

2색 칠하기란, 다음 두 조건을 만족하면서 그래프의 정점을 모두 색칠할 수 있는지 묻는 문제이다. 2개의 색이 존재한다. 인접한 두 정점은 색깔이 다르다. 그래프가 주어질 때, 2색 칠하기가 가능한지 출력하는 프로그램을 작성하시오. 예를 들어, 아래의 그래프는 2색 칠하기가 가능한 그래프이며, 정점을 색칠한 결과는 다음과 같다.


입력

첫째 줄에 정점의 개수 N과 간선의 개수 M이 주어진다. ( 1 ≤ N ≤ 10,000, 1 ≤ M ≤ 100,000 ) 둘째 줄부터 간선의 정보가 주어진다. 각 줄은 두 개의 숫자 a, b로 이루어져 있으며, 이는 정점 a와 정점 b가 연결되어 있다는 의미이다.(0 ≤ a, b ≤ N-1)

출력

주어진 그래프에 대하여 2색 칠하기를 할 수 있으면 YES, 할 수 없으면 NO를 출력한다.

예제 입력

case 1)

9 10
0 1
0 2
0 3
1 5
2 5
3 4
5 6
5 8
6 7
7 8

 

case 2)

9 11
0 1
0 2
0 3
1 5
2 5
3 4
4 5
5 6
5 8
6 7
7 8

예제 출력

case 1) YES

case 2) NO

 

 

 

2. 풀이

이 문제는 비교적으로 간단하다. 정점에 방문했다는 것과 방문했을 때의 색의 정보를 함께 넣어주고, 이미 방문한 점이였다면 기존의 색과 다음으로 변경될 색의 정보를 비교하면 된다.

 

DFS 풀이는 다음과 같다.

import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;

class Graph {
    private ArrayList<ArrayList<Integer>> graph;

    public Graph(int nodeSize) {
        graph = new ArrayList<>();

        for(int i = 0; i < nodeSize + 1; i++) {
            graph.add(new ArrayList<>());
        }
    }

    public void put(int n, int m) {
        graph.get(n).add(m);
        graph.get(m).add(n);
    }

    public ArrayList<Integer> getNode(int n) {
        return graph.get(n);
    }
}

public class Main {

    private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    private static int n;
    private static int m;
    private static Graph graph;
    private static boolean[] isVisited;
    private static char[] colored;

    private static boolean flag;

    public static void main(String[] args) throws IOException {

        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        graph = new Graph(n);
        isVisited = new boolean[n+1];
        colored = new char[n+1];

        for(int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            graph.put(a, b);
        }

        dfs(0, 'R');

        if(flag) bw.write("NO\n");
        else bw.write("YES\n");

        br.close();
        bw.flush();
        bw.close();
    }

    private static void dfs(int v, char color) {
        isVisited[v] = true;
        colored[v] = color;
        for(int i = 0; i < graph.getNode(v).size(); i++) {
            int w = graph.getNode(v).get(i);
            if(!isVisited[w]) {
                if(color == 'R') dfs(w, 'G');
                else if(color == 'G') dfs(w, 'R');
            }
            if(isVisited[w]) {
                if(color == colored[w]) flag = true;
            }
        }
    }
}

BFS 풀이는 다음과 같다.

import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

class Graph {
    private ArrayList<ArrayList<Integer>> graph;

    public Graph(int nodeSize) {
        graph = new ArrayList<>();

        for(int i = 0; i < nodeSize + 1; i++) {
            graph.add(new ArrayList<>());
        }
    }

    public void put(int n, int m) {
        graph.get(n).add(m);
        graph.get(m).add(n);
    }

    public ArrayList<Integer> getNode(int n) {
        return graph.get(n);
    }

    public boolean isAdjacent(int n, int m) {
        for(int i = 0; i < graph.get(n).size(); i++) {
            if(graph.get(n).get(i) == m) return true;
        }
        return false;
    }
}

public class Main {

    private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    private static int n;
    private static int m;
    private static Graph graph;
    private static boolean[] isVisited;
    private static char[] colored;

    private static boolean flag;

    public static void main(String[] args) throws IOException {

        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        graph = new Graph(n);
        isVisited = new boolean[n+1];
        colored = new char[n+1];

        for(int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            graph.put(a, b);
        }

        bfs(0, 'R');

        if(flag) bw.write("NO\n");
        else bw.write("YES\n");

        br.close();
        bw.flush();
        bw.close();
    }

    private static void bfs(int v, char color) {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(v);
        isVisited[v] = true;
        colored[v] = color;

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

            for(int i = 0; i < n; i++) {
                if(graph.isAdjacent(i, w) && !isVisited[i]) {
                    queue.add(i);
                    isVisited[i] = true;
                    if(colored[w] == 'R') {
                        colored[i] = 'G';
                    } else {
                        colored[i] = 'R';
                    }
                }
                if(graph.isAdjacent(i, w) && isVisited[i]) {
                    if(colored[w] == colored[i]) flag = true;
                }
            }
        }
    }
}
728x90