POJ 1274 The Perfect Stall 【二分图匹配】
裸的二分图匹配
匈牙利算法:
#include <cstdio>#include <cstring>#include <iostream>#include <vector>#include <algorithm>using namespace std;#define N 420#define INF 0x3f3f3f3fclass Dinic {public: int c[N][N], n, s, t, l[N], e[N]; int flow(int maxf = INF) { int left = maxf; while (build()) left -= push(s, left); return maxf - left; } int push(int x, int f) { if (x == t) return f; int &y = e[x], sum = f; for (; y<n; y++) if (c[x][y] > 0 && l[x]+1==l[y]) { int cnt = push(y, min(sum, c[x][y])); c[x][y] -= cnt; c[y][x] += cnt; sum -= cnt; if (!sum) return f; } return f-sum; } bool build() { int m = 0; memset(l, -1, sizeof(l)); l[e[m++]=s] = 0; for (int i=0; i<m; i++) for (int y=0; y<n; y++) if (c[e[i]][y] > 0 && l[y]<0) l[e[m++]=y] = l[e[i]] + 1; memset(e, 0, sizeof(e)); return l[t] >= 0; }} net;int main() { int n, m, a, b; while (scanf("%d%d", &n, &m) == 2) { memset(net.c, 0, sizeof(net.c)); net.s = 0, net.t = n+m+1, net.n = n+m+2; for (int i=1; i<=n; i++) net.c[net.s][i] = 1; for (int i=1; i<=m; i++) net.c[n+i][net.t] = 1; for (int i=1; i<=n; i++) { cin >> a; while (a--) { cin >> b; net.c[i][n+b] = INF; } } cout << net.flow() << endl; } return 0;}