https://www.acmicpc.net/problem/1707
1707번: 이분 그래프
입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수
www.acmicpc.net
위키백과:
그래프 이론에서, 이분 그래프(二分graph, 영어: bipartite graph)란 모든 꼭짓점을 빨강과 파랑으로 색칠하되, 모든 변이 빨강과 파랑 꼭짓점을 포함하도록 색칠할 수 있는 그래프이다.
이 외에도 홀수개의 사이클이 없어야 한다는데 이게 이해가 잘 안됐었는데 그림으로 다시 확인해보면
홀수 사이클에선 파랑 - 파랑 으로 같은 색끼리 연결이 될 수 밖에 없기 때문에 이분 그래프가 아니다.
DFS나 BFS를 통해 색을 칠하며 정점을 탐색하는 것이 중요한 문제였다.
코드에서는 DFS에서 탐색을 하면서, 이분 그래프 여부도 같이 체크해줬다.
color는 방문전에는 0으로 시작하고, 탐색 시 color % 2 + 1 을 통해 색을 반전시켜줬다.
color = 1인 경우 1 % 2 + 1 = 2
color = 2인 경우 2 % 2 + 1 = 1
memset도 필요한 부분까지만 리셋해주며 코드를 좀 더렵혀봤다.
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int color[20001];
bool isBipartiteGraph;
void DFS(vector<vector<int>>& list, int current, int nextColor)
{
int size = list[current].size();
for (int i = 0; i < size; ++i)
{
if (!isBipartiteGraph)
{
return;
}
int next = list[current][i];
if (color[next] == 0)
{
color[next] = nextColor;
DFS(list, next, nextColor % 2 + 1);
}
else if (color[current] == color[next])
{
isBipartiteGraph = false;
return;
}
}
}
int main()
{
int testCase;
int v, e;
int from, to;
cin.tie(0);
cin >> testCase;
while (testCase--)
{
vector<vector<int>> list;
isBipartiteGraph = true;
cin >> v >> e;
list.resize(v + 1);
memset(color, 0, sizeof(int) * (v + 1));
for (int i = 0; i < e; ++i)
{
cin >> from >> to;
list[from].push_back(to);
list[to].push_back(from);
}
for (int i = 1; i <= v; ++i)
{
if (color[i] == 0)
{
color[i] = 1;
}
DFS(list, i, color[i] % 2 + 1);
}
if (isBipartiteGraph)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
}
'Algorithm > Baekjoon Online Judge' 카테고리의 다른 글
[백준 문제 C++] 1063 킹 (0) | 2021.09.06 |
---|---|
[백준 문제 C++] 1074 Z (0) | 2021.08.30 |
[백준 문제 C++] 1193 분수찾기 (0) | 2021.08.24 |
[백준 문제 C++] 2150 Strongly Connected Component (0) | 2021.08.23 |
[백준 문제 C++] 1300 K번째 수 (0) | 2021.08.22 |