Cod sursa(job #1712229)

Utilizator Cristy94Buleandra Cristian Cristy94 Data 2 iunie 2016 12:53:41
Problema Tribut Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 3.13 kb
#include<stdio.h>
#include<vector>
#include<cstring>

#define uniune(x) x + 201
#define NMAX 401
#define sz [NMAX][NMAX]
#define INF 0x3f3f3f3f

using namespace std;

int N, M, T, S, D, uniuni;
// Vectori
int tata[NMAX],viz[NMAX],c[NMAX];
// Matrici
int cap sz,flux sz;
vector <int> a[NMAX];

int bf(){
    memset(viz,0,sizeof(viz));

    int p = 1, u = 1;
    c[1] = S;
    viz[S] = 1;

    while(p <=u ) {
        int nod = c[p];

        for(vector<int>::iterator it = a[nod].begin(); it != a[nod].end(); ++it) {
           if(!viz[*it] && cap[nod][*it] > flux[nod][*it]) {
              viz[*it] = 1;
              tata[*it] = nod;
              c[++u] = *it;

              if(*it == D)
                  return 1;
           }
        }

        p++;
    }

    return 0;
}
int main() {

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

    scanf("%d", &T);

    while(T--) {

        // Resetam memoria pentru testul curent
        memset(tata, 0, sizeof(tata));
        memset(cap, 0, sizeof(cap));
        memset(flux, 0, sizeof(flux));
        for(int i = 0; i < NMAX; ++i)
            a[i].clear();

        scanf("%d%d",&N,&uniuni);

        // Setam sursa si destinatia
        S = 0;
        D = NMAX - 1;

        // sursa -> sist
        for(int i = 1; i <= N; ++i) {
            int tribut;

            scanf("%d", &tribut);

            if(tribut == 0) continue;

            cap[S][i] = tribut;
            a[S].push_back(i);
            a[i].push_back(S);
        }

        // sist->uniune, uniune->destinatie
        for(int i = 1; i <= uniuni; ++i) {
            int P, c;
            scanf("%d%d", &P, &c);

            int id = uniune(i);

            // uniune->destinatie
            if(c != 0) {
                cap[id][D] = c;
                a[id].push_back(D);
                a[D].push_back(id);
            }

            // sist->uniune
            for(int j = 1; j <= P; ++j) {
                int sist;
                scanf("%d", &sist);

                cap[sist][id] = INF;
                a[sist].push_back(id);
                a[id].push_back(sist);
            }
        }


        int flow=0;
        while(bf()){
             for(vector<int>::iterator it = a[D].begin(); it != a[D].end(); ++it) {
                if(viz[*it]) {

                    tata[D] = *it;
                    int fmn = INF;

                    // Calculam fluxul maxim de la D la S pe drumul curent
                    for(int nod = D; nod != S && fmn > 0;nod = tata[nod])
                        fmn= min(fmn, cap[tata[nod]][nod]-flux[tata[nod]][nod]);

                    // Actualizam matricea de flux cu fluxul gasit
                    if(fmn!=0)
                        for(int nod=D;nod!=S;nod=tata[nod]) {
                            flux[tata[nod]][nod]+=fmn;
                            flux[nod][tata[nod]]-=fmn;
                        }

                    // Adaugam la solutie
                    flow += fmn;
                }
            }
        }

        printf("%d\n",flow);
    }

    return 0;
}