Cod sursa(job #1709606)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 28 mai 2016 13:03:19
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 1.89 kb
#include <stdio.h>
#include <vector>
#include <queue>

#define maxdim 205
#define INF (1 << 29)

using namespace std;

int n, m, S, D;
int cap[maxdim][maxdim], F[maxdim][maxdim], viz[maxdim], T[maxdim];
vector<int> G[maxdim];

inline bool bfs() {
  for (int i = 1; i <= D; ++i) {
    viz[i] = T[i] = 0;
  }
  queue<int> q;
  q.push(S);
  viz[S] = 1;

  int ok = 0;
  while (!q.empty()) {
    int nod = q.front(); q.pop();
    for (int vecin : G[nod]) {
      if (!viz[vecin] && cap[nod][vecin] > F[nod][vecin]) {
        if (vecin == D) {
          ok = 1;
          continue;
        }
        T[vecin] = nod;
        viz[vecin] = 1;
        q.push(vecin);
      }
    }
  }

  return ok;
}

int flux() {
  int f = 0;

  while (bfs()) {

    for (int nod : G[D]) {
      T[D] = nod;
      int crtf = INF, x;
      for (x = D; T[x]; x = T[x]) {
        crtf = min(crtf, cap[T[x]][x] - F[T[x]][x]);
      }
      if (x != S) {
        crtf = 0;
      }
      f += crtf;
      for (x = D; T[x]; x = T[x]) {
        F[T[x]][x] += crtf;
        F[x][T[x]] -= crtf;
      }
    }
  }

  return f;
}

void add_edge(int x, int y) {
  G[x].push_back(y);
  G[y].push_back(x);
}

int main() {
  freopen("tribut.in", "r", stdin);
  freopen("tribut.out", "w", stdout);

  int tests; scanf("%d", &tests);
  while (tests--) {
    scanf("%d %d", &n, &m);
    S = n + m + 1, D = n + m + 2;
    for (int i = 1; i <= n; ++i) {
      scanf("%d", &cap[S][i]);
      add_edge(S, i);
    }
    for (int i = 1; i <= m; ++i) {
      int no, maxt; scanf("%d %d", &no, &maxt);
      cap[i + n][D] = maxt;
      add_edge(i + n, D);
      for (int j = 1; j <= no; ++j) {
        int x; scanf("%d", &x);
        cap[x][i + n] = INF;
        add_edge(x, i + n);
      }
    }
    printf("%d\n", flux());

    for (int i = 1; i <= D; ++i) {
      G[i].clear();
      for (int j = 1; j <= D; ++j) {
        cap[i][j] = F[i][j] = 0;
      }
    }
  }

  return 0;
}