코딩뚠뚠

[백준문제풀이] 1707 이분그래프 본문

알고리즘 문제풀이/백준문제풀이

[백준문제풀이] 1707 이분그래프

로디네로 2020. 12. 31. 01:39
반응형

 

풀이일시 : 2020-10-10

 

문제 :

그래프의 정점의 집합을 둘로 분할하여, 각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있을 때, 그러한 그래프를 특별히 이분 그래프 (Bipartite Graph) 라 부른다.

그래프가 입력으로 주어졌을 때, 이 그래프가 이분 그래프인지 아닌지 판별하는 프로그램을 작성하시오.

입력 :

입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수 E(1≤E≤200,000)가 빈 칸을 사이에 두고 순서대로 주어진다. 각 정점에는 1부터 V까지 차례로 번호가 붙어 있다. 이어서 둘째 줄부터 E개의 줄에 걸쳐 간선에 대한 정보가 주어지는데, 각 줄에 인접한 두 정점의 번호가 빈 칸을 사이에 두고 주어진다.

ex)

2 //테스트케이스 수

3 2 //정점, 간선

1 3 //간선정보1

2 3 //간선정보2

4 4 //정점, 간선

1 2 //간선정보1

2 3 //간선정보2

3 4 //간선정보3

4 2 //간선정보4

 

출력 :

K개의 줄에 걸쳐 입력으로 주어진 그래프가 이분 그래프이면 YES, 아니면 NO를 순서대로 출력한다.

ex)

YES

NO

 

 

풀이 : 

- visit을 빨강 1 파랑 2로 두어 구분해준다.

- BFS로 풀이한다.

dbstndi6316.tistory.com/63

 

[기본문제풀이] BFS 너비우선탐색

풀이 일시 : 2020-08-30 ​ BFS : 탐색 - 하나의 정점으로부터 시작하여 차례대로 모든 정점들을 한번씩 방문하는 것. 그 중 한 방법인 너비우선탐색은 루트 노드에서 시작해서 인접한 노드를 먼저 탐

dbstndi6316.tistory.com

#include <iostream>
#include <queue>
#include <vector>
#include <string.h>
#define MAX 20001

using namespace std;

vector <int> v[MAX];
int visit[MAX]; //여기다가 0,1 뿐만이아니라 방문X:0 빨강:1 파랑:2 로 표시
int result;
int K, V, E;

void bfs(int x, int y) {
	queue <int> q;
	visit[x] = y; //RED로 초기화
	q.push(x);
	while (!q.empty()) {
		int x = q.front();
		q.pop();

		for (int i = 0; i < v[x].size(); i++) { //인접 중에
			int z = v[x][i];
			if (visit[z] == 0) { //방문하지 않은 것 중
				if (visit[x] == 1) { //빨간색이면
					visit[z] = 2; //파란색으로 넣기
					q.push(z); //큐에넣기
				}
				else if (visit[x] == 2) { //파란색이면
					visit[z] = 1; //빨간색으로 넣기
					q.push(z);
				}
			}
		}
	}
}

bool isBipartiteGraph() { //이분그래프인가?!
	for (int i = 1; i <= V; i++) {
		for (int j = 0; j < v[i].size(); j++) { //빠져나온 후 모든경우에 대해 탐색
			int z = v[i][j];
			if (visit[i] == visit[z]) {
				return 0;
			}
		}
	}
	return 1;
}

int main() {
	int re;
	cin >> K;
	for (int i = 0; i < K; i++) {
		cin >> V >> E;//노드의 수 , 간선의 수
		for (int i = 0; i < E; i++) {
			int x, y;
			cin >> x >> y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		for (int i = 1; i <= V; i++) { //노드를 살펴본다.
			if (visit[i] == 0) { //색이 칠해져있지 않은 노드만 따져본다.
				bfs(i, 1); //빨간색:1 부터 칠하고 시작한다.
			}
		}

		if (isBipartiteGraph()) {
			printf("YES\n");
		}
		else {
			printf("NO\n");
		}

		for (int i = 0; i < MAX; i++) {
			v[i].clear(); //한번 수행후엔 벡터를 다 비워줘야 함
		}
		memset(visit, 0, sizeof(visit)); //방문, 색 나타낸 배열도 비워주기
	}
	return 0;
} 

 

추가자료 : 

dbstndi6316.tistory.com/28

 

[개념정리] memset함수

메모리를 조작하는 함수로는 대표적으로 memset, memcpy, memmove, memcmp 등이 있다. 그 중 메모리를 초기화하는 memset을 알아본다. ​ memset함수란 메모리의 내용을 원하는 크기만큼 특정 값으로 세팅할

dbstndi6316.tistory.com

dbstndi6316.tistory.com/25

 

[개념정리] vector container

vector 란 C++ STL vector는 list계열의 container 종류이다. 자료구조의 스택과 구조가 비슷하다. vector를 생성하면 메모리 heap에 생성되며 동적할당 된다. ​ vector 사용 선언 및 초기화 vector<자료형> 변수.

dbstndi6316.tistory.com

 

반응형