from palette import colorful_colors

[백준] 1707 이분 그래프 with C++ 본문

알고리즘/문제풀이

[백준] 1707 이분 그래프 with C++

colorful-palette 2025. 2. 16. 17:01

https://www.acmicpc.net/problem/1707

 

 

💡문제 아이디어

이분그래프 판별 문제.

같은 그룹(색깔)끼리는 이어져 있으면 안된다.

탐색하면서 빈 노드가 있으면 다른 색깔로 칠하고, 같은 색깔이었으면 이분그래프 조건이 아니므로 0을 return한다

 

 

 

💡문제 코드

// 백준 1707 이분 그래프
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

int K, V, E;
vector <int> alis[20001];
int visited[20001];

// 테스트케이스 전 그래프 초기화
void init() {
	memset(alis, 0, sizeof(alis));
	memset(visited, 0, sizeof(visited));
}

// 테스트케이스 당 그래프 생성
void input() {
	cin >> V >> E;
	for (int i = 0; i < E; i++) {
		int from, to;
		cin >> from >> to;
		alis[from].push_back(to);
		alis[to].push_back(from);
	}
}

// DFS로 풀이 - 하나를 돌면 다른 그룹으로 설정 
int dfs(int nowNode, int colorNum) {

	visited[nowNode] = colorNum;

	int size = alis[nowNode].size();
		for (int i = 0; i < size; i++) {
		// 다음 노드가 같은 색깔, 이분그래프 불가
		int target = alis[nowNode][i];
		if (visited[target] == colorNum) {
			return 0;
		}
		// 다음 노드가 다른 색깔이었다면 그냥 지나가기
		else if (visited[target] == -colorNum) {
			continue;
		}
		// 비어있는 노드였다면 다른 색깔로 칠하기  
		else {
			int ret = dfs(target, -colorNum);
			if (ret == 0) return 0;	// dfs로 타고 올라온 결과가 0이면 0
		}
	}
	return 1;
}

int main() {
	//freopen("sample_input.txt", "r", stdin);

	cin >> K;
	for (int i = 0; i < K; i++) {
		init();
		input();

		// dfs 타서 해당 테스트케이스가 이분그래프인지 분별
		// 모든 node가 연결되지 않을 수 있을 수 있기 때문에, 모든 노드에 대해 테스트한다.
		int flag = 1;
		for (int i = 1; i <= V; i++) {

			if (!visited[i]) {
				int dfsResult = dfs(i, 1);
				if (dfsResult == 0) {
					flag = 0;
					break;
				}
			}
		}

		// 출력하기 
		if (flag == 1) cout << "YES\n";
		else cout << "NO\n";
	}

	return 0;
}

 

 

💡메모리풀 이용

참고 블로그: https://bloodstrawberry.tistory.com/30

// 백준 1707 이분 그래프 - 메모리풀 이용
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

int K, V, E;

struct NODE {
	int node;
	struct NODE* next;	// NODE형 구조체를 가리키는 포인터
};

// 전역변수로 메모리 미리 선언, 메모리 위치 나타내는 index
NODE HEAD[20001];	
NODE POOL[200001 * 2];	// 그래프 edge들 정보를 담을 곳 
int visited[20001];

int pcnt;

// 테스트케이스 전 그래프 초기화
void init() {
	pcnt = 0;	// 메모리 풀 초기화
	for (int i = 1; i <= V; i++) HEAD[i].next = 0;
	memset(visited, 0, sizeof(visited));
}

void makeEdge(int from, int to) {
	NODE* nd = &POOL[pcnt++];
	nd->node = to;
	nd->next = HEAD[from].next;
	HEAD[from].next = nd;
}

// 테스트케이스 당 그래프 생성
void input() {
	cin >> V >> E;
	for (register int i = 0; i < E; i++) {
		int from, to;
		cin >> from >> to;
		makeEdge(from, to);
		makeEdge(to, from);
	}
}

// DFS로 풀이 - 하나를 돌면 다른 그룹으로 설정 
int dfs(int nowNode, int colorNum) {

	visited[nowNode] = colorNum;

	for (NODE* p = HEAD[nowNode].next; p; p=p->next) {
		// 다음 노드가 같은 색깔, 이분그래프 불가
		if (visited[p->node] == colorNum) {
			return 0;
		}
		// 다음 노드가 다른 색깔이었다면 그냥 지나가기
		else if (visited[p->node] == -colorNum) {
			continue;
		}
		// 비어있는 노드였다면 다른 색깔로 칠하기  
		else {
			int ret = dfs(p->node, -colorNum);
			if (ret == 0) return 0;	// dfs로 타고 올라온 결과가 0이면 0
		}
	}
	return 1;
}

int main() {
	//freopen("sample_input.txt", "r", stdin);

	cin >> K;
	for (int i = 0; i < K; i++) {
		init();
		input();

		// dfs 타서 해당 테스트케이스가 이분그래프인지 분별
		// 모든 node가 연결되지 않을 수 있을 수 있기 때문에, 모든 노드에 대해 테스트한다.
		int flag = 1;
		for (int i = 1; i <= V; i++) {

			if (!visited[i]) {
				int dfsResult = dfs(i, 1);
				if (dfsResult == 0) {
					flag = 0;
					break;
				}
			}
		}

		// 출력하기 
		if (flag == 1) cout << "YES\n";
		else cout << "NO\n";
	}

	return 0;
}