POJ 3041 Asteroids(最小覆盖数)

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
今日推荐