POJ 3041個の小惑星(カバーの最小数)

POJ3041

質問の意味:

N×N個のグリッドはグリッドがKの障害物が、あります。あなたは武器を持っていますか、あなたは武器を使用するたびに特定の行またはグリッドの列にそのすべての障害をクリアすることができます。あなたは少なくとも必要なことは何回武器缶を頼みますすべての障害物グリッドをクリアしますか?

最小のカバレッジの問題、最小カバレッジ=最大マッチングアルゴリズムは、直接ハンガリーとすることができます

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
int head[N * 2], nex[N * 2], to[N * 2], match[N];
int cnt;
bool vis[N];
void pre_work() {
	memset(head, -1, sizeof head);
	memset(nex, -1, sizeof nex);
	memset(match, -1, sizeof match);
	cnt = 0;
	memset(vis, false, sizeof vis);
}
void add(int a, int b) {
	cnt++;
	nex[cnt] = head[a];
	head[a] = cnt;
	to[cnt] = b;
}
bool dfs(int p) {
	for (int i = head[p]; i != -1; i = nex[i]) {
		int y = to[i];
		if (!vis[y]) {
			vis[y] = true;
			if (match[y] == -1 || dfs(match[y])) {
				match[y] = p;
				return true;
			}
		}
	}
	return false;
}
int main()
{
	ios::sync_with_stdio(0);
	int n, k;
	pre_work();
	cin >> n >> k;
	for (int i = 0; i < k; i++) {
		int a, b;
		cin >> a >> b;
		add(a, b + n);
		add(b + n, a);
	}
	int res = 0;
	for (int i = 1; i <= n; i++) {
		memset(vis, false, sizeof vis);
		if (dfs(i))++res;
	}
	cout << res << "\n";
	return 0;
}

 

公開された143元の記事 ウォン称賛11 ビュー8195

おすすめ

転載: blog.csdn.net/weixin_43701790/article/details/103758839