POJ - 1548 二分图最小路径覆盖解法

题目链接

思路

扫地机器人的路径可以看做二分图的匹配,因此这道题求的是二分图的最小路径匹配。即:点的个数 – 二分图的最大匹配
注意:机器人只能往右下角走
ps:这里只是其中一种解法,还有其他解法,比如最大流

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int N = 1e3 + 11;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
-------------------------------------------------------板子
int line[N][N];
int vis[N];
int match[N];
int n;
bool dfs(int m) {
	int i;
	for (i = 1; i <= n; i++) {
		if (line[m][i] && !vis[i]) {
			vis[i] = 1;
			if (match[i] == -1 || dfs(match[i])) {
				match[i] = m;
				return true;
			}
		}
	}
	return false;
}
int matching() {
	memset(match , -1 , sizeof(match));
	int ans = 0;
	for (int i = 1; i <= n ; i++) {
		memset(vis, 0, sizeof(vis));
		if (dfs(i))
			ans++;
	}
	return ans;
}
------------------------------------------------------
struct Node {
	int x, y;
} node[N];
int main() {
	int a, b;
	while (scanf("%d%d", &a, &b) && (a != -1 && b != -1)) {
		memset(line, 0 , sizeof line);
		if (!a && !b) {
			printf("0\n");
			continue;
		}
		n = 0;
		while (a && b) {
			node[++n].x = a;
			node[n].y = b;
			scanf("%d %d", &a, &b);
		}
		for (int i = 1; i <= n ; i++) { //只能往右下角走
			for (int j = i + 1 ; j <= n ; j++) {
				if (node[i].x <= node[j].x && node[i].y <= node[j].y)
					line[i][j] = 1;
				else if (node[i].x >= node[j].x && node[i].y >= node[j].y)
					line[j][i] = 1;
			}
		}
		printf("%d\n", n - matching());
	}
	return 0;
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页