※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 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 |