※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2570번 문제인 비숍2이다.
문제는 아래 링크를 확인하자.

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

 

2570번: 비숍2

서양장기인 체스에는 대각선 방향으로 움직일 수 있는 비숍(bishop)이 있다. < 그림 1 >과 같이 크기가 5인 정사각형 체스판 위에 B라고 표시된 곳에 비숍이 있을 때 비숍은 대각선 방향으로 움직여

www.acmicpc.net

한 방향의 대각선으로 움직일 수 있는 범위를 하나의 노드로 생각하여, 서로 다른 방향의 두 대각선에 대해 둘이 공통된 칸을 지난다면 그 두 대각선범위 사이에 에지가 있는 것으로 보아 이분그래프(bipartite graph)를 구할 수 있다. 이 이후는 단순한 maximum bipartite matching 문제이다.

 

움직일 수 있는 범위로 대각선을 나누는 것에 대한 구현을 잘 해주자.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

bool board[100][100];
int diag1[100][100];
int diag2[100][100];

vector<int> G[5001];
int visited[5001];
int matching[5001];

int bipartite(int current) {
	if (visited[current]) return 0;
	visited[current] = 1;
	for (auto node : G[current]) {
		if (matching[node] == 0) {
			matching[node] = current;
			return 1;
		}
		if (bipartite(matching[node])) {
			matching[node] = current;
			return 1;
		}
	}
	return 0;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int N, M; cin >> N >> M;
	while (M--) {
		int r, c; cin >> r >> c;
		r--; c--;
		board[r][c] = 1;
	}

	int idx = 1;
	for (int i = 0; i < N; i++) {
		for (int k = 0; k <= i; k++) {
			if (board[i - k][k]) idx++;
			else diag1[i - k][k] = idx;
		}
		idx++;
	}
	for (int i = 0; i < N - 1; i++) {
		for (int k = 0; k <= i; k++) {
			if (board[N - 1 - i + k][N - 1 - k]) idx++;
			else diag1[N - 1 - i + k][N - 1 - k] = idx;
		}
		idx++;
	}

	idx = 1;
	for (int i = 0; i < N; i++) {
		for (int k = 0; k < N - i; k++) {
			if (board[i + k][k]) idx++;
			else diag2[i + k][k] = idx;
		}
		idx++;
	}
	for (int i = 1; i < N; i++) {
		for (int k = 0; k < N - i; k++) {
			if (board[k][i + k]) idx++;
			else diag2[k][i + k] = idx;
		}
		idx++;
	}

	for (int r = 0; r < N; r++) {
		for (int c = 0; c < N; c++) {
			if (board[r][c]) continue;
			G[diag1[r][c]].push_back(diag2[r][c]);
		}
	}

	int ans = 0;
	for (int i = 1; i <= 5000; i++) {
		memset(visited, 0, sizeof(visited));
		ans += bipartite(i);
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 15480 // C++] LCA와 쿼리  (0) 2021.07.20
[BOJ 3351 // C++] 삼각 분할  (0) 2021.07.19
[BOJ 5398 // C++] 틀렸습니다  (0) 2021.07.17
[BOJ 1574 // C++] 룩 어택  (0) 2021.07.16
[BOJ 13344 // C++] Chess Tournament  (0) 2021.07.15

+ Recent posts