poj 3041 二分图最小点覆盖=二分图最大匹配
构图:把行作为x集合,把列当作y集合,如果某个位置有障碍,相应的x和y连边
每一条边对应一个障碍。问题转化为选择最小的点覆盖全部的边。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 505; int uN, vN; bool g[MAXN][MAXN]; int xM[MAXN], yM[MAXN]; bool chk[MAXN]; bool searchPath(int u) { int v; for(v = 0; v < vN; v++) if(g[u][v] && !chk[v]) { chk[v] = true; if(yM[v] == -1 || searchPath(yM[v])) { yM[v] = u; xM[u] = v; return true; } } return false; } int maxMatch() { int u, ret = 0; memset(xM, -1, sizeof(xM)); memset(yM, -1, sizeof(yM)); for(u = 0; u < uN; u++) if(xM[u] == -1) { memset(chk, false, sizeof(chk)); if(searchPath(u))ret++; } return ret; } int main() { int n,k, a, b; while( scanf("%d%d", &n, &k)!= EOF) { memset(g, 0, sizeof(g)); uN=vN =n; while(k--) { scanf("%d%d",&a, &b); a--; b--; g[a][b] = 1; } printf("%d\n", maxMatch()); } // system("pause"); return 0; }