※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 1799번 문제인 비숍이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/1799
1799번: 비숍
첫째 줄에 체스판의 크기가 주어진다. 체스판의 크기는 10이하의 자연수이다. 둘째 줄부터 아래의 예와 같이 체스판의 각 칸에 비숍을 놓을 수 있는지 없는지에 대한 정보가 체스판 한 줄 단위로
www.acmicpc.net
좌상단에서 우하단으로 향하는 대각선들과 우상단에서 좌하단으로 향하는 대각선들을 노드로, 비숍을 놓을 수 있는 칸에서 교차하는 두 대각선 사이의 관계를 에지로 하는 그래프를 모델링하자. 이 때, 위 그래프는 각 방향별 대각선의 집합으로 둘로 나뉘는 이분그래프가 되고 주어진 문제는 이 이분그래프에서의 최대 매칭을 찾는 문제와 같아진다.
최대 이분매칭을 구하는 알고리즘을 이용해 문제를 해결하자.
번외로, N x N (N>1) 체스판 위에 서로 교차하지 않게끔 비숍을 놓을 수 있는 최대 개수는 2N-2개와 같다는 관찰을 이용하면 브루트포스를 이용해 문제를 해결할 수도 있을 것이다.
아래는 제출한 소스코드이다.
#define NODE 20
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int N;
int idx1[10][10], idx2[10][10];
vector<int> G[NODE];
int visited[NODE];
int matching[NODE];
int bpfunc(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 (bpfunc(matching[node])) {
matching[node] = current;
return 1;
}
}
return 0;
}
int bipartitematching() {
int ret = 0;
for (int i = 1; i <= N; i++) {
memset(visited, 0, sizeof(visited));
ret += bpfunc(i);
}
return ret;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
idx1[r][c] = r + c + 1, idx2[r][c] = N - r + c;
}
}
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
bool x; cin >> x;
if (x) G[idx1[r][c]].emplace_back(idx2[r][c]);
}
}
N = N * 2 - 1;
cout << bipartitematching();
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 3284 // C++] MASS (0) | 2023.08.25 |
---|---|
[BOJ 3283 // C++] BARCODE (0) | 2023.08.24 |
[BOJ 2546 // C++] 경제학과 정원영 (0) | 2023.08.22 |
[BOJ 15822 // C++] Ah-Choo! (0) | 2023.08.22 |
[BOJ 6765 // C++] Icon Scaling (0) | 2023.08.22 |