Cod sursa(job #1709070)

Utilizator hrazvanHarsan Razvan hrazvan Data 28 mai 2016 10:47:31
Problema Tribut Scor 0
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.36 kb
#include <cstdio>
#include <cstring>
#define MAXN 100
#define MAXM 100
#define MAXMCH 10200
#define INF 2000000000
int ut[MAXN + MAXM + 2], nd[2 * MAXMCH], nxt[2 * MAXMCH], cpc[2 * MAXMCH], fol[2 * MAXMCH], dr;
int sp[MAXN + MAXM + 2], prev[MAXN + MAXM + 2];
char tr[MAXN + MAXM + 2];
int q[MAXN + MAXM + 2];

inline int min2(int a, int b){
  return a < b ? a : b;
}

inline void add(int x, int y, int c){
  nd[dr] = y;
  nxt[dr] = ut[x];
  fol[dr] = 0;
  cpc[dr] = c;
  ut[x] = dr;
  dr++;
}

char bfs(int s, int d){
  memset(tr, 0, sizeof tr);
  memset(prev, 0, sizeof prev);
  int a, poz, st = 0, dr = 1;
  q[0] = s;
  tr[0] = 1;
  while(st < dr){
    a = q[st];
    st++;
    poz = ut[a];
    while(poz != -1){
      if(!tr[nd[poz]] && cpc[poz] > fol[poz]){
        tr[nd[poz]] = 1;
        q[dr] = nd[poz];
        prev[nd[poz]] = a;
        sp[nd[poz]] = poz;
        dr++;
      }
      poz = nxt[poz];
    }
  }
  return tr[d];
}

inline int flux(int s, int d){
  int suma = 0, augm, poz, p;
  while(bfs(s, d)){
    poz = ut[d];
    while(poz != -1){
      prev[d] = nd[poz];
      sp[d] = poz - 1;
      if(tr[nd[poz]] && cpc[poz - 1] > fol[poz - 1]){
        p = d;
        augm = INF;
        while(p != 0){
          augm = min2(augm, cpc[sp[p]] - fol[sp[p]]);
          p = prev[p];
        }
        suma += augm;
        p = d;
        while(p != 0){
          fol[sp[p]] += augm;
          if(sp[p] & 1)
            fol[sp[p] - 1] -= augm;
          else
            fol[sp[p] + 1] += augm;
          p = prev[p];
        }
      }
      poz = nxt[poz];
    }
  }
  return suma;
}

int main(){
  FILE *in = fopen("tribut.in", "r");
  FILE *out = fopen("tribut.out", "w");
  int t, n, m, i, s, d, x, nr, j;
  fscanf(in, "%d", &t);
  for(; t > 0; t--){
    fscanf(in, "%d%d", &n, &m);
    dr = 0;
    memset(ut, -1, sizeof ut);
    s = 0;
    d = n + m + 1;
    for(i = 1; i <= n; i++){
      fscanf(in, "%d", &x);
      add(i, d, x);
      add(d, i, 0);
    }
    for(i = 1; i <= m; i++){
      fscanf(in, "%d%d", &nr, &x);
      add(s, i + n, x);
      add(i + n, s, 0);
      for(j = 1; j <= nr; j++){
        fscanf(in, "%d", &x);
        add(i + n, x, INF);
        add(x, i + n, 0);
      }
    }
    fprintf(out, "%d\n", flux(s, d));
  }
  fclose(in);
  fclose(out);
  return 0;
}