반응형
https://www.acmicpc.net/problem/1707
1707번: 이분 그래프
입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V와 간선의 개수 E가 빈 칸을 사이에
www.acmicpc.net
문제 요약
주어진 그래프가 이분 그래프인지 판별하는 문제이다.
더보기
이분 그래프(Bipartite Graph)?
그래프의 정점의 집합을 둘로 분할했을 때, 각 집합에 속한 정점끼리 서로 인접하지 않게 할 수 있는 그래프이다.
접근
이분 그래프를 모르는 상태에서 문제를 접하다보니 구현에 실수가 조금 있었다.
양방향 그래프를 입력 받고, visit배열을 통해 방문 여부를 확인하며 평범한 DFS를 구현했다.
이분 그래프를 만족시키는지 확인하기 위해 DFS함수의 두 번째 인자로 해당 정점이 속해있는 집합 번호를 넘겨주고, 그 번호를 해당 정점의 visit배열에 저장하는 식으로 구현했다.
예를 들어, 1번 정점부터 DFS를 시작한다고 하자. 1번 정점은 집합 1에 속한다. ( visit[1] = 1 )
다음 정점으로 DFS를 수행할 때는 다음 정점이 들어가야 할 집합의 번호를 넘겨준다.
이렇게 DFS를 수행하다 보면 next정점이 이미 방문한 적이 있는데, 현재 정점과 집합의 번호가 같은 경우가 있다. 이 경우에는 이분 그래프의 성질이 깨지므로 false를 리턴한다. 그렇지 않으면 이분 그래프를 만족하므로 나머지 경우에 대해선 true를 리턴한다.
반복문을 통해 1번 정점부터 N번 정점까지 DFS를 수행하면서 각 수행 결과를 모두 AND한 값이 true이면 이분 그래프이다.
#include <iostream>
#include <queue>
using namespace std;
int N, M, T, a, b;
vector<vector<int> > V;
vector<int> visit;
bool dfs(int n, int c) {
visit[n] = c;
bool temp = true;
for (int i : V[n]) {
if (visit[i] == c) return false;
if (!visit[i]) temp &= dfs(i, c == 2 ? 1 : 2);
}
return temp;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
for (cin >> T; T--;) {
cin >> N >> M;
V = vector<vector<int> >(N + 1);
visit = vector<int>(N + 1, 0);
for (; M--;) {
cin >> a >> b;
V[a].push_back(b);
V[b].push_back(a);
}
bool ans = true;
for (int i = 1; i <= N; i++) {
if (!visit[i]) ans &= dfs(i, 1);
}
cout << (ans ? "YES" : "NO") << '\n';
}
}반응형
'문제 풀이' 카테고리의 다른 글
| BOJ 25639 : 수열과 최대 상승 쿼리 [C++] (0) | 2023.02.08 |
|---|---|
| BOJ 11779 : 최소비용 구하기 2 [C++] (0) | 2023.02.06 |
| BOJ 3769 : 최댓값 [C++] (1) | 2023.02.02 |
| BOJ 22940 : 선형 연립 방정식 [C++] (0) | 2023.01.31 |
| BOJ 1005 : ACM Craft (0) | 2023.01.29 |