baekjoon

[백준] 1760 N-Rook

윤만석 2023. 2. 28. 14:34

문제

N-Queen 문제를 풀어본 일이 있을 것이다. 격자판에 N개의 Queen을 배치하되, 각 Queen이 서로를 공격할 수 없게 배치하려면 N은 최대 얼마까지 가능한지를 알아내는 문제이다.

이번에는 Rook을 가지고 같은 문제를 풀어 보자. Rook은 격자판의 같은 열, 혹은 같은 행에 다른 말이 있을 경우, 그 말을 공격할 수 있는 말이다.

다만, 이 경우에 문제가 그 가치를 확보하기 위해서는, 격자판을 약간 변형해야 한다. 격자판에 벽과 구덩이를 도입하자.

벽을 사이에 두고 있는 두 Rook은, 서로 볼 수 없으므로, 서로 공격할 수가 없다. 물론 벽이 놓여 있는 격자에는 Rook을 놓을 수 없다.

반면, 구덩이를 사이에 두고 있는 두 Rook은 서로 공격을 시도한다. (아마 공격 도중에 구덩이에 빠지겠지만.) 따라서 두 Rook이 구덩이를 사이에 두고 마주보도록 배치해서는 안 된다. 또, 구덩이를 파 놓은 격자에도 Rook을 놓을 수 없다.

격자판의 모양이 주어졌을 때, Rook을 가장 많이 배치하기 위한 방법을 알아내는 프로그램을 작성하시오.

입력

첫째 줄에 격자의 크기를 나타내는 두 자연수 N, M이 주어진다. 격자가 N행 M열로 이루어져 있다는 의미이다. (1 ≤ N, M ≤ 100) 둘째 줄부터는 격자의 모양을 나타내는 정보가 한 줄에 한 행씩 주어진다. 0은 빈 격자, 1은 구덩이가 파인 격자, 2는 벽이 놓인 격자를 의미한다.

출력

 

첫째 줄에 배치할 수 있는 Rook의 최대 개수를 출력한다.

 

구덩이에는 룩을 배치할 수 없지만, 같은행에서는 서로 공격을 할 수있습니다.

벽에는 룩을 배치할 수도 업고, 공격할수도없습니다.

이분매칭으로 해결합니다.

 

	#include<bits/stdc++.h>
	#define FAST ios_base::sync_with_stdio(false);cin.tie(NULL)
	#define mset(v) memset(v,0,sizeof(v));
	#define rep(i,a) for(int i=0;i<a;++i)
	#define REP(i,a) for(int i=1;i<=a;++i)

	using namespace std;

	typedef long long ll;
	typedef pair<int, int> pi;
	typedef tuple<int, int, int>ti;
	typedef vector<int> vi;
	typedef vector<vector<int>> vvi;
	int dy[] = { -1,0,1,0 }, dx[] = { 0,1,0,-1 };
	int mp[101][101], m[101][101], v[10001], d[10001];
	int N, M, R, C, ans;
	vi adj[10001];

	bool dfs(int k) {
		for (auto r : adj[k]) {
			if (v[r])continue;
			v[r] = 1;
			if (!d[r] || dfs(d[r])) {
				d[r] = k;
				return 1;
			}
		}
		return 0;
	}
	int main() {
		FAST;
		cin >> N >> M;
		rep(i, N)rep(j, M)cin >> mp[i][j];
		rep(i, N) {
			bool f = 0;
			rep(j, M) {
				if (mp[i][j] == 2) 
					f = 0;
				
				else {
					if (!f)R++;
					m[i][j] = R;
					f = 1;
				}
		
			}
		}
		rep(i, M) {
			bool f = 0;
			rep(j, N) {
				if (mp[j][i] == 2)
					f = 0;
				else if(mp[j][i]==0) {
					if (!f)C++;
					adj[m[j][i]].push_back(C);
					f = 1;
				}
			}
		}
		REP(i, R) {
			mset(v);
			if (dfs(i))ans++;
		}
		cout << ans;
	}