[Algorithm/Graph] 이분 그래프(bipartite graph) 판별하기

2024. 7. 13. 19:14·Computer Science/Algorithm

이분 그래프란?

  • 정점을 두 개의 집합으로 나눌 수 있는 그래프
  • 그래프의 모든 에지는 서로 다른 집합에 속한 정점끼리 연결되어야 한다.
  • ex) 학생 목록과 수업 목록을 모델링하는 경우
  • ex) 스트리핑 플랫폼에서 영화 목록과 시청자 사이의 관계를 모델링하는 경우
  • 최대 매칭 또는 최소 정점 커버 문제와 같은 NP-완전 문제들이 이분 그래프에서는 다항시간으로 풀 수 있다.
    • 따라서 주어진 그래프가 이분 그래프인지 아닌지 판별하는 것은 매우 중요하다

 

이분 그래프의 구현

DFS를 변형하여 만들 수 있다.

  1. 1번 정점부터 DFS를 시작한다고 가정한다(1번 정점을 스택에 추가한다)
  2. 스택에 방문하지 않은 정점이 남아있다면 스택에서 정점을 하나 꺼내고 이를 현재 정점으로 설정한다
  3. 이전 정점에 할당된 색상이 검은색이면 현재 정점에 빨간색을 할당한다. 반대로 이전 정점에 할당된 색상이 빨간색이면 현재 정점에 검은색을 할당한다
  4. 현재 정점과 인접한 정점들 중에 아직 방문하지 않은 정점들을 스택에 넣고, 현재 정점을 방문한 것으로 설정한다
  5. 모든 정점이 색상이 지정될 때 까지 2~4단계를 반복한다. 알고리즘 종료 시 모든 정점에 색상이 칠해져 있다면 이 그래프는 이분 그래프이다.
  6. 만약 탐색을 진행하다가 만나게 된 정점이 이미 방문한 정점이고, 이 정점의 색상이 현재 할당할 색상과 다른 색상이면 알고리즘을 종료하고, 해당 그래프가 이분 그래프가 아니라고 판별한다.

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;
}

 

'Computer Science > Algorithm' 카테고리의 다른 글

[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
[Algorithm/Greedy] 동전 거스름돈 문제  (0) 2024.07.04
'Computer Science/Algorithm' 카테고리의 다른 글
  • [Algorithm/Graph] 다익스트라 최단 경로 알고리즘(Dijkstra's algorithm)
  • [Algorithm/Graph] 프림의 최소 신장 트리 알고리즘(prim's algorithm)
  • [Algorithm/Graph] 깊이 우선 탐색(DFS, Depth-First scrach)
  • [Algorithm/Graph] 너비 우선 탐색(BFS, Breadth-First Scrach)과 구현(에지 리스트, 인접 행렬, 인접 리스트)
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기 (463)
      • 개발 일지 (0)
        • Performance (0)
        • TroubleShooting (0)
        • Refactoring (0)
        • Code Style, Convetion (0)
        • Architecture (0)
      • Software Engineering (36)
        • Test (8)
        • 이론 (18)
        • Clean Code (10)
      • Java (72)
        • Basic (5)
        • Core (21)
        • Collection (7)
        • 멀티스레드&동시성 (13)
        • IO, Network (8)
        • Reflection, Annotation (3)
        • Modern Java(8~) (13)
        • JVM (2)
      • Spring (53)
        • Framework (12)
        • MVC (23)
        • Transaction (3)
        • AOP (11)
        • Boot (0)
        • AI (0)
      • DB Access (16)
        • Jdbc (1)
        • JdbcTemplate (0)
        • JPA (14)
        • Spring Data JPA (0)
        • QueryDSL (0)
      • Computer Science (130)
        • Data Structure (27)
        • OS (14)
        • Database (10)
        • Network (21)
        • 컴퓨터구조 (6)
        • 시스템 프로그래밍 (23)
        • Algorithm (29)
      • HTTP (8)
      • Infra (1)
        • Docker (1)
      • 프로그래밍언어론 (15)
      • Programming Language(Sub) (77)
        • Kotlin (1)
        • Python (25)
        • C++ (51)
        • JavaScript (0)
      • FE (11)
        • HTML (1)
        • CSS (9)
        • React (0)
        • Application (1)
      • Unix_Linux (0)
        • Common (0)
      • PS (13)
        • BOJ (7)
        • Tip (3)
        • 프로그래머스 (0)
        • CodeForce (0)
      • Book Review (4)
      • Math (3)
        • Linear Algebra (3)
      • AI (7)
        • DL (0)
        • ML (0)
        • DA (0)
        • Concepts (7)
      • 프리코스 (4)
      • Project Review (6)
      • LegacyPosts (11)
      • 모니터 (0)
      • Diary (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
lumana
[Algorithm/Graph] 이분 그래프(bipartite graph) 판별하기
상단으로

티스토리툴바