이분 그래프란?
- 정점을 두 개의 집합으로 나눌 수 있는 그래프
- 그래프의 모든 에지는 서로 다른 집합에 속한 정점끼리 연결되어야 한다.
- ex) 학생 목록과 수업 목록을 모델링하는 경우
- ex) 스트리핑 플랫폼에서 영화 목록과 시청자 사이의 관계를 모델링하는 경우
- 최대 매칭 또는 최소 정점 커버 문제와 같은 NP-완전 문제들이 이분 그래프에서는 다항시간으로 풀 수 있다.
- 따라서 주어진 그래프가 이분 그래프인지 아닌지 판별하는 것은 매우 중요하다
이분 그래프의 구현
DFS를 변형하여 만들 수 있다.
- 1번 정점부터 DFS를 시작한다고 가정한다(1번 정점을 스택에 추가한다)
- 스택에 방문하지 않은 정점이 남아있다면 스택에서 정점을 하나 꺼내고 이를 현재 정점으로 설정한다
- 이전 정점에 할당된 색상이 검은색이면 현재 정점에 빨간색을 할당한다. 반대로 이전 정점에 할당된 색상이 빨간색이면 현재 정점에 검은색을 할당한다
- 현재 정점과 인접한 정점들 중에 아직 방문하지 않은 정점들을 스택에 넣고, 현재 정점을 방문한 것으로 설정한다
- 모든 정점이 색상이 지정될 때 까지 2~4단계를 반복한다. 알고리즘 종료 시 모든 정점에 색상이 칠해져 있다면 이 그래프는 이분 그래프이다.
- 만약 탐색을 진행하다가 만나게 된 정점이 이미 방문한 정점이고, 이 정점의 색상이 현재 할당할 색상과 다른 색상이면 알고리즘을 종료하고, 해당 그래프가 이분 그래프가 아니라고 판별한다.
C++ 코드
template <typename T>
auto bipartite_check(const Graph<T>& G)
{
stack<unsigned> stack;
set<unsigned> visited; // 방문한 정점
stack.push(1); // 1번 정점부터 시작
enum class colors { NONE, BLACK, RED };
colors current_color { colors::BLACK }; // 다음 정점에 칠할 색상
vector<colors> vertex_colors(G.vertices(), colors::NONE);
while (!stack.empty())
{
auto current_vertex = stack.top();
stack.pop();
// 현재 정점을 이전에 방문하지 않았다면
if (visited.find(current_vertex) == visited.end())
{
visited.insert(current_vertex);
vertex_colors[current_vertex] = current_color;
if (current_color == colors::RED)
{
cout << current_vertex << "번 정점: 빨간색" << endl;
current_color = colors::BLACK;
}
else
{
cout << current_vertex << "번 정점: 검정색" << endl;
current_color = colors::RED;
}
// 인접한 정점 중에서 방문하지 않은 정점이 있다면 스택에 추가
for (auto e : G.edges(current_vertex))
if (visited.find(e.dst) == visited.end())
stack.push(e.dst);
}
// 현재 정점이 이미 방문한 정점이고,
// 현재 칠할 색상과 같은 색상이 칠해져 있다면 이분 그래프가 아님.
else if (vertex_colors[current_vertex] != colors::NONE &&
vertex_colors[current_vertex] != current_color)
return false;
}
// 모든 정점에 색상이 칠해졌으면 이분 그래프가 맞음
return true;
}
'Algorithm > Graph' 카테고리의 다른 글
[Algorithm/Graph] 벨만-포드 알고리즘(Bellman-Ford algorithm)과 음수 가중치 사이클 찾기 (0) | 2024.07.13 |
---|---|
[Algorithm/Graph] 다익스트라 최단 경로 알고리즘(Dijkstra's algorithm) (0) | 2024.07.13 |
[Algorithm/Graph] 프림의 최소 신장 트리 알고리즘(prim's algorithm) (0) | 2024.07.13 |
[Algorithm/Graph] 깊이 우선 탐색(DFS, Depth-First scrach) (0) | 2024.07.12 |
[Algorithm/Graph] 너비 우선 탐색(BFS, Breadth-First Scrach)과 구현(에지 리스트, 인접 행렬, 인접 리스트) (0) | 2024.07.12 |