poj 3281

拆点建图,跑EK,拆掉牛即可。

#include 
#include 
#include 
#include 
#define MAX 501
#define INF 0x3f3f3f3f

using namespace std;
int n, f, d;
int gra[MAX][MAX];
int visit[MAX];
int S, E;
int pre[MAX];
stack Q;
bool E_K() {
  memset(visit, 0, sizeof(visit));
  visit[0] = 1;
  pre[0] = -1;
  while (!Q.empty()) {
    Q.pop();
  }

  Q.push(S);
  while (!Q.empty()) {
    int front = Q.top();
    Q.pop();
    for (size_t i = S; i <= E; i++) {
      if (!visit[i] && gra[front][i] > 0) {
        Q.push(i);
        visit[i] = 1;
        pre[i] = front;
      }
    }
  }
  return visit[E] == 1;
}

int main() {
  while (~scanf("%d%d%d", &n, &f, &d)) {
    S = 0;
    E = 2 * n + f + d + 1;

    memset(gra, 0, sizeof(gra));
    int c1, c2, F, D;
    for (size_t i = 1; i <= n; i++) {
      scanf("%d%d", &c1, &c2);
      for (size_t j = 1; j <= c1; j++) {
        scanf("%d", &F);
        gra[F][f + 2 * i - 1] = 1;
        gra[S][F] = 1;
      }
      for (size_t k = 1; k <= c2; k++) {
        scanf("%d", &D);
        gra[f + 2 * i][f + 2 * n + D] = 1;
        gra[f + 2 * n + D][E] = 1;
      }
    }

    for (int i = 1; i <= 2 * n; i++) {
      gra[f + 2 * i - 1][f + 2 * i] = 1;
    }

    int path_flow = INF;
    int max_flow = 0;
    while (E_K()) {
      for (int v = E; v != S; v = pre[v]) {
        int u = pre[v];
        path_flow = min(path_flow, gra[u][v]);
      }

      for (int v = E; v != S; v = pre[v]) {
        int u = pre[v];
        gra[u][v] -= path_flow;
        gra[v][u] += path_flow;
      }
      max_flow += path_flow;
    }
    printf("%d\n", max_flow);
  }

  return 0;
}

你可能感兴趣的:(poj 3281)