# 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;
}


06-11 576
08-04 325
02-18 321
03-09 1003
02-12 630
05-10 584
08-09 527
08-02 3568
08-11 528
03-20 737
12-17