Cod sursa(job #1774399)

Utilizator R4DIC4LTeodorescu Oana Maria R4DIC4L Data 8 octombrie 2016 21:34:32
Problema Tribut Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.66 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,cap sz,flux sz,tata[NMAX],viz[NMAX],c[NMAX], S, D, T;
int uniuni;
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(int i=0;i<(int)a[nod].size();++i)
           if(!viz[a[nod][i]] && cap[nod][a[nod][i]] > flux[nod][a[nod][i]]) {
              viz[a[nod][i]]=1;
              c[++u]=a[nod][i];
              tata[a[nod][i]]=nod;
              if(a[nod][i] == D)
                  return 1;
           }
        p++;
    }
 
    return 0;
}
int main() {
 
    freopen("tribut.in", "r", stdin);
    freopen("tribut.out","w", stdout);
 
    scanf("%d", &T);
 
    while(T--) {
 
        memset(tata, 0, sizeof(tata));
        memset(cap, 0, sizeof(cap));
        memset(flux, 0, sizeof(flux));
 
        scanf("%d%d",&N,&uniuni);
 
        for(int i = 0; i < NMAX; ++i)
            a[i].clear();
 
        S = 0;
        D = NMAX - 1;
 
        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);
        }
 
        for(int i = 1; i <= uniuni; ++i) {
            int P, c;
            scanf("%d%d", &P, &c);
 
            int id = uniune(i);
 
                if(c != 0) {
                    cap[id][D] = c;
                    a[id].push_back(D);
                    a[D].push_back(id);
                }
 
            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(int i=0;i<a[D].size();++i){
                if ( viz [a[D][i]] ){
 
                    tata[D]=a[D][i];
                    int fmn=INF;
 
                    for(int nod=D;nod!=S && fmn > 0;nod=tata[nod])
                        fmn=min(fmn, cap[tata[nod]][nod]-flux[tata[nod]][nod]);
 
                    if(fmn!=0)
                        for(int nod=D;nod!=S;nod=tata[nod]) {
                            flux[tata[nod]][nod]+=fmn;
                            flux[nod][tata[nod]]-=fmn;
                        }
 
                    flow+=fmn;
                }
            }
        }
        printf("%d\n",flow);
    }
	return 0;
}