匈牙利算法求最大匹配。
把x和y看作两个集合,如果 (x, y)有一个asteroid,就在x和y之间连一条边,这样就有了一个二分图。
这里因为不需要求出具体的匹配,所以只需不断寻找交错链(也就是增广路、交错轨),每找到一条,结果加1(因为找到一条交错链意味着匹配数+1)
代码:
/*
Poj: 3041 Asteroids
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 505
using namespace std;
int graph[Max][Max];
int N, K;
bool checked[Max];
int xM[Max], yM[Max];
int MaxMatch(void);
bool SearchPath(int u);
int main()
{
//freopen("data.in", "rb", stdin);
while(scanf("%d%d", &N, &K) != EOF) {
for(int i = 0; i < K; i++) {
int r, c;
scanf("%d%d", &r, &c);
graph[r-1][c-1] = 1;
}
printf("%d\n", MaxMatch());
}
return 0;
}
int MaxMatch(void)
{
int matches = 0;
for(int i = 0; i < Max; i++)
xM[i] = yM[i] = -1;
for(int u = 0; u < N; u++) {
if(xM[u] == -1) {
memset(checked, false, sizeof(checked));
if(SearchPath(u))
matches++;
}
}
return matches;
}
bool SearchPath(int u)
{
for(int v = 0; v < N; v++) { //寻找增广路
if(graph[u][v] == 1 && !checked[v]) {
checked[v] = true;
if(yM[v] == -1 || SearchPath(yM[v])) {
yM[v] = u;
xM[u] = v;
return true;
}
}
}
return false;
}