이번 문제는 백준 골드 4 이분 그래프 문제이다.
제목을 보고 그래프 문제이길래 흥미로워 보여 풀기로 마음 먹었다.
문제를 한 번 차근차근 읽어보도록 하자.
최대 2만개의 정점과, 20만개의 간선이 주어질 수 있다.
위 제약 조건 아래에서 그래프가 주어졌을 때, 이분 가능한지 판단하라.
일단 이 문제를 풀려면 이분 그래프가 무엇인지 알아야 한다.
이분 그래프(Bipartite graph)
이분 그래프는 이름 그대로, 두 집합으로 분할이 가능한 집합이다.
조금 더 자세하게 정의하면 각 정점들을 두 개의 집합으로 나누었을 때,
같은 집합에 포함된 정점들 간에는 간선이 없어야 한다.
아래와 같은 그래프가 이분 그래프이며, 색깔로 집합을 구분한다.
자 이제 이분 그래프가 무엇인지 알았으니, 어떻게 판별할지 고민해보자.
가장 큰 특징인 같은 집합의 노드끼리는 연결되지 않았음을 어떻게 확인할까?
집합에 정점을 집어넣는 모든 경우의 수를 다 탐색해보아야 할까?
완전탐색은 정점이 2만개이기 떄문에 시간이 말도 안되게 걸릴 것이다.
DFS + 색깔
위의 그래프에서 색깔을 이용해서 각 집합을 구분했었다.
DFS를 돌려서 색깔로 두 집합으로 구분이 가능한지 살펴 볼 수 있을까?
색깔로 취급할 int[]
배열을 하나 만들어서 색을 체크하도록 하고,
DFS를 우선 한 번 돌려서 두 집합으로 구분을 한 다음 더 작은 집합을 찾는다.
정점의 수가 더 작은 집합의 정점들로 부터 각각 DFS를 돌렸을 때,
색깔 배열의 상태가 변하지 않는다면 이분 그래프일 것이다.
이 논리를 코드로 구현했을 때, 시간초과가 발생하지 않을까?
곰곰히 생각해보니, 시간 초과가 문제가 아니라는 생각이 들었다.
애초에 이 논리는 끊어진 정점이 있다는 가정하에 이루어지며,
모두 이어진 그래프의 경우에는 판별이 불가능하다.
진짜 DFS + 색깔
사실 아이디어는 맞았는데, 논리가 잘못되었었다.
훨씬 간단하게 이분 그래프를 분별할 수 있는 방법이 인터넷에 있었다.
그것은 바로 DFS를 탐색하며 이어진 정점은 계속 반대 색깔로 갱신하는 것이다.
아래와 같이 코드로 구현하였다.
정점을 계속 반대 색으로 갱신한 뒤, 핵심은 이를 검사할 때에 있다.
만약 모든 연결된 정점을 검사할 때 연결된 정점에서 같은 색이 발견된다면?
그럼 이 그래프는 이분 그래프가 될 수 없다는 의미가 된다!
왜냐하면, 어떤 두 정점이 있다면 그 둘은 반드시 다른 색을 가져야 하기 때문이다.
그게 바로 이분 그래프의 정의 이기 때문이다.
위와 같은 코드로 구현할 수 있다.
여러개의 테스트 케이스가 존재하기 때문에, 마지막엔 배열을 초기화 해준다.
혼자 생각해내기에는 아직 무리가 있는 문제였다.
이분 그래프를 판별 해낼 수 있는 아이디어를 생각하기가 매우 어려웠다.
이럴 때 일수록 더욱 개념을 잘 생각해야 하는 게 수학 문제를 푸는 것 같다.