룰루랄라 코딩기록장

[Baekjoon] 백준 1707번 이분그래프 본문

Algorithm/그래프

[Baekjoon] 백준 1707번 이분그래프

Jeonnnng 2019. 5. 8. 15:02

1707번 이분그래프 문제 풀이

문제

  • 그래프의 정점의 집합을 둘로 분할하여, 각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있을 때, 그러한 그래프를 특별히 이분 그래프 (Bipartite Graph) 라 부른다.
    그래프가 입력으로 주어졌을 때, 이 그래프가 이분 그래프인지 아닌지 판별하는 프로그램을 작성하시오.

입력

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

출력

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

예제

입력 
2
3 2
1 3
2 3
4 4
1 2
2 3
3 4
4 2
출력
YES
NO

해결방법

  • A,B로 나누어진 이분 그래프가 되기 위해서는 A에 속한 정점들이 1을 가지고 있고, B에 속한 정점들은 2를 가지고 있을 때, 본인과 인접 정점들이 가지고 있는 수가 달라야 성립된다.
  • 따라서 시작 정점에 번호를 부여하고, 간선으로 이어진 다른 정점에 시작 정점과 다른 번호를 부여한 후 인접 정점들에 대해서 동일한 번호가 있는지 비교하여 이분 그래프인지 확인해야 한다.
void dfs(int start, int c) {
    color[start] = c;
    for (int i = 0; i < a[start].size(); i++) {
        int next = a[start][i];
        if (color[next] == 0) {
            dfs(next, 3 - c);
        }
    }
}
  • 기본 DFS코드와 다르게 매개변수를 추가로 하나 더 받는다. 번호를 마킹하기위한 매개변수 c로서 color배열에 1과 2를 저장한다.
    • (3-c) -> 3-2=1 , 3-1=2
    • color배열은 정점이 가지고 있는 번호를 저장한다
for (int i = 1; i <= v; i++) {
    if (color[i] == 0) {
        dfs(i, 1);
    }
}
bool result= true;
for (int i = 1; i <= v; i++) {
    for (int k = 0; k < a[i].size(); k++) {
        int j = a[i][k];
        if (color[i] == color[j]) {
            result = false;
        }
    }
}
  • color이 확정되지 않은 정점부터 dfs를 실행한다.
  • color[i]는 현재 정점 , color[j]는 인접 정점의 값을 나타낸다. 따라서 두 값이 같은 경우 이분 그래프가 성립되지 않는다.

코드

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;;
vector<int> a[20001];
int color[20001];

void dfs(int start, int c) {
    color[start] = c;
    for (int i = 0; i < a[start].size(); i++) {
        int next = a[start][i];
        if (color[next] == 0) {
            dfs(next, 3 - c);
        }
    }
}


int main() {
    int t;
    cin >> t;
    while (t--) {
        int v, e;
        cin >> v >> e;
        for (int i = 1; i <= v; i++) {
            a[i].clear();
            color[i] = 0;
        }
        for (int i = 0; i < e; i++) {
            int x, y;
            cin >> x >> y;
            a[x].push_back(y);
            a[y].push_back(x);
        }
        for (int i = 1; i <= v; i++) {
            if (color[i] == 0) {
                dfs(i, 1);
            }
        }
        bool result= true;
        for (int i = 1; i <= v; i++) {
            for (int k = 0; k < a[i].size(); k++) {
                int j = a[i][k];
                if (color[i] == color[j]) {
                    result = false;
                }
            }
        }
        printf("%s\n", result ? "YES" : "NO");
    }
}
Comments