룰루랄라 코딩기록장
[Baekjoon] 백준 1707번 이분그래프 본문
1707번 이분그래프 문제 풀이
문제
- 그래프의 정점의 집합을 둘로 분할하여, 각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있을 때, 그러한 그래프를 특별히 이분 그래프 (Bipartite Graph) 라 부른다.
그래프가 입력으로 주어졌을 때, 이 그래프가 이분 그래프인지 아닌지 판별하는 프로그램을 작성하시오.
입력
- 입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수 E(1≤E≤200,000)가 빈 칸을 사이에 두고 순서대로 주어진다. 각 정점에는 1부터 V까지 차례로 번호가 붙어 있다. 이어서 둘째 줄부터 E개의 줄에 걸쳐 간선에 대한 정보가 주어지는데, 각 줄에 인접한 두 정점의 번호가 빈 칸을 사이에 두고 주어진다.
출력
- K개의 줄에 걸쳐 입력으로 주어진 그래프가 이분 그래프이면 YES, 아니면 NO를 순서대로 출력한다.
예제
입력
2
3 2
1 3
2 3
4 4
1 2
2 3
3 4
4 2
출력
YES
NO
해결방법
- A,B로 나누어진 이분 그래프가 되기 위해서는 A에 속한 정점들이 1을 가지고 있고, B에 속한 정점들은 2를 가지고 있을 때, 본인과 인접 정점들이 가지고 있는 수가 달라야 성립된다.
- 따라서 시작 정점에 번호를 부여하고, 간선으로 이어진 다른 정점에 시작 정점과 다른 번호를 부여한 후 인접 정점들에 대해서 동일한 번호가 있는지 비교하여 이분 그래프인지 확인해야 한다.
void dfs(int start, int c) {
color[start] = c;
for (int i = 0; i < a[start].size(); i++) {
int next = a[start][i];
if (color[next] == 0) {
dfs(next, 3 - c);
}
}
}
- 기본 DFS코드와 다르게 매개변수를 추가로 하나 더 받는다. 번호를 마킹하기위한 매개변수 c로서 color배열에 1과 2를 저장한다.
- (3-c) -> 3-2=1 , 3-1=2
- color배열은 정점이 가지고 있는 번호를 저장한다
for (int i = 1; i <= v; i++) {
if (color[i] == 0) {
dfs(i, 1);
}
}
bool result= true;
for (int i = 1; i <= v; i++) {
for (int k = 0; k < a[i].size(); k++) {
int j = a[i][k];
if (color[i] == color[j]) {
result = false;
}
}
}
- color이 확정되지 않은 정점부터 dfs를 실행한다.
- color[i]는 현재 정점 , color[j]는 인접 정점의 값을 나타낸다. 따라서 두 값이 같은 경우 이분 그래프가 성립되지 않는다.
코드
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;;
vector<int> a[20001];
int color[20001];
void dfs(int start, int c) {
color[start] = c;
for (int i = 0; i < a[start].size(); i++) {
int next = a[start][i];
if (color[next] == 0) {
dfs(next, 3 - c);
}
}
}
int main() {
int t;
cin >> t;
while (t--) {
int v, e;
cin >> v >> e;
for (int i = 1; i <= v; i++) {
a[i].clear();
color[i] = 0;
}
for (int i = 0; i < e; i++) {
int x, y;
cin >> x >> y;
a[x].push_back(y);
a[y].push_back(x);
}
for (int i = 1; i <= v; i++) {
if (color[i] == 0) {
dfs(i, 1);
}
}
bool result= true;
for (int i = 1; i <= v; i++) {
for (int k = 0; k < a[i].size(); k++) {
int j = a[i][k];
if (color[i] == color[j]) {
result = false;
}
}
}
printf("%s\n", result ? "YES" : "NO");
}
}
'Algorithm > 그래프' 카테고리의 다른 글
[Baekjoon] 백준 7576번 토마토 (0) | 2019.05.16 |
---|---|
[Baekjoon] 백준 2178번 미로탐색(지나온 경로탐색 추가) (0) | 2019.05.16 |
[Baekjoon] 백준 4963번 섬의개수 (0) | 2019.05.14 |
[Baekjoon] 백준 2667번 단지번호붙이기 (0) | 2019.05.08 |
[Baekjoon] 백준 11724번 연결요소의 개수 (0) | 2019.05.08 |
Comments