※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 1574번 문제인 룩 어택이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/1574
1574번: 룩 어택
첫째 줄에 체스판의 크기 R과 C가 주어지고, 빈 칸의 개수 N이 주어진다. 둘째 줄부터 N개의 줄에 빈 칸의 좌표가 주어진다. 좌표는 (행, 열)의 형태로 주어지고, 가장 윗 행은 1번 행이고, 가장 왼
www.acmicpc.net
"빈 칸"에 룩을 놓을 수 없음에 주의하자.
한 열에 룩을 하나씩만 놓을 수 있으므로, 각 행마다 겹치지 않게 열을 하나씩 최대한 고르면서 가능한 한 많은 열을 고르는 것으로 문제를 생각할 수 있다. 이 상황은 각 행과 열을 노드로 하는 이분그래프(bipartite graph)로 모델링을 할 수 있다. 이 그래프에서 maximum bipartite matching 알고리즘을 이용하면 문제를 해결할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
bool board[301][301];
vector<int> G[301];
int visited[301];
int matching[301];
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 R, C, N; cin >> R >> C >> N;
while (N--) {
int x, y; cin >> x >> y;
board[x][y] = 1;
}
for (int r = 1; r <= R; r++) {
for (int c = 1; c <= C; c++) {
if (board[r][c]) continue;
G[r].push_back(c);
}
}
int ans = 0;
for (int i = 1; i <= R; i++) {
memset(visited, 0, sizeof(visited));
ans += bipartite(i);
}
cout << ans;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 2570 // C++] 비숍2 (0) | 2021.07.18 |
---|---|
[BOJ 5398 // C++] 틀렸습니다 (0) | 2021.07.17 |
[BOJ 13344 // C++] Chess Tournament (0) | 2021.07.15 |
[BOJ 15701 // C++] 순서쌍 (0) | 2021.07.14 |
[BOJ 20294 // C++] 에어컨 설치 (0) | 2021.07.13 |