Cod sursa(job #1710476)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 29 mai 2016 00:16:24
Problema Tribut Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 3.61 kb
#include <cstdio>
#include <bitset>
#include <cstring>
#include <deque>
#include <vector>
#include <algorithm>

const int SIZE = 2e2 + 5;
const int INFI = 0x3f3f3f3f;
const int C1 = 0;
const int C2 = 100;

int start_node, finish_node, n, m, q, x, k, answer, minim;
int capacity[SIZE][SIZE], flow[SIZE][SIZE], father[SIZE];
std::bitset <SIZE> marked; std::vector <int> edge[SIZE]; std::deque <int> my_queue;

inline bool bfs( int start_node, int finish_node ) {
    bool ok = false;
    my_queue.clear(); my_queue.push_back(start_node);
    marked.reset(); marked[start_node] = 1;
    
    while( !my_queue.empty() ) {
        int node = my_queue.front();
        
        std::vector <int> :: iterator it;
        for( it = edge[node].begin(); it != edge[node].end(); it ++ ) {
            int next_node = *it;
            
            if( !marked[next_node] && flow[node][next_node] < capacity[node][next_node] ) {
                marked[next_node] = 1;
                father[next_node] = node;
                my_queue.push_back(next_node);
                
                if( next_node == finish_node )
                    ok = true;
            }
        }
        my_queue.pop_front();
    }
    
    return ok;
}

int main( int argc, const char *argv[] ) {
    
    freopen( "tribut.in" , "r", stdin  );
    freopen( "tribut.out", "w", stdout );
    
    start_node = SIZE - 1; finish_node = SIZE - 2;
    
    scanf( "%d", &q );
    for( int t = 1; t <= q; t ++ ) {
        scanf( "%d %d", &n, &m );
        
        for( int i = 1; i <= n; i ++ ) {
            scanf( "%d", &x );
            capacity[i + C2][finish_node] = x;
            
            edge[i + C2].push_back(finish_node);
            edge[finish_node].push_back(i + C2);
        }
        
        for( int i = 1; i <= m; i ++ ) {
            scanf( "%d %d", &k, &x );
            capacity[start_node][i + C1] = x;
            
            edge[start_node].push_back(i + C1);
            edge[i + C1].push_back(start_node);
            
            for( int j = 1; j <= k; j ++ ) {
                scanf( "%d", &x );
                capacity[i + C1][x + C2] = INFI;
                
                edge[i + C1].push_back(x + C2);
                edge[x + C2].push_back(i + C1);
            }
        }
        
        while( bfs(start_node, finish_node) ) {
            std::vector <int> :: iterator it;
            
            for( it = edge[finish_node].begin(); it != edge[finish_node].end(); it ++ ) {
                int aux_node = *it;
                
                if( marked[aux_node] && flow[aux_node][finish_node] < capacity[aux_node][finish_node] ) {
                    minim = capacity[aux_node][finish_node] - flow[aux_node][finish_node];
                    
                    for( int node = aux_node; node != start_node; node = father[node] )
                        minim = std::min( minim, capacity[ father[node] ][node] - flow[ father[node] ][node] );
                    
                    answer += minim;
                    flow[aux_node][finish_node] += minim;
                    flow[finish_node][aux_node] -= minim;
                    
                    for( int node = aux_node; node != start_node; node = father[node] ) {
                        flow[ father[node] ][node] += minim;
                        flow[node][ father[node] ] -= minim;
                    }
                }
            }
        }
        
        printf( "%d\n", answer );
        
        answer = 0;
        memset( capacity, 0, sizeof(capacity) );
        memset( flow, 0, sizeof(flow) );
        
        for( int i = 0; i < SIZE; i ++ )
            edge[i].resize(0);
    }
    
    return 0;
}