Pagini recente » Cod sursa (job #786068) | Cod sursa (job #1624428) | Cod sursa (job #1628728) | Cod sursa (job #3262170) | Cod sursa (job #1709376)
#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;
}