Pagini recente » Cod sursa (job #47222) | Cod sursa (job #1865903) | Cod sursa (job #1624297) | Cod sursa (job #1154127) | Cod sursa (job #1709570)
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#define NMAX 209
#define oo (1<<30)
using namespace std;
int N, M, cap[ NMAX ][ NMAX ], flow[ NMAX ][ NMAX ], d[ NMAX ], T[ NMAX ], inQ[ NMAX ], bani[ NMAX ], cash[ NMAX ];
queue<int> Q;
vector<int> G[NMAX];
bool BFS(int S, int D) {
for (int i = 0; i <= N; ++i) {
d[ i ] = oo;
T[ i ] = 0;
inQ[ i ] = 0;
}
d[ S ] = 0;
T[ S ] = S;
Q.push( S );
inQ[ S ] = 1;
while (!Q.empty()) {
int node = Q.front();
Q.pop();
inQ[ node ] = 0;
if (node == D) {
continue;
}
for (vector<int>::iterator it = G[node].begin(); it != G[node].end(); ++it) {
if (d[ node ] + 1 < d[ *it] && flow[ node ][ *it ] < cap[ node ][ *it ]) {
d[ *it ] = d[ node ] + 1;
T[ *it ] = node;
if (!inQ[ *it ]) {
inQ[ *it ] = 1;
Q.push( *it );
}
}
}
}
return T[ D ];
}
int maxflow(int S, int D) {
int sol = 0;
while (BFS(S, D)) {
for (vector<int>::iterator it = G[ D ].begin(); it != G[ D ].end(); ++it) {
if (T[ *it] && flow[ *it ][ D ] < cap[ *it ][ D ]) {
T[ D ] = *it;
int minFlow = oo;
for (int node = D; node != S; node = T[ node]) {
minFlow = min( minFlow, cap[ T[node] ][ node ] - flow[ T[node] ][ node ]);
}
if (minFlow > 0) {
sol += minFlow;
for (int node = D; node != S; node = T[ node]) {
flow[ T[node] ][ node ] += minFlow;
flow[ node ][ T[node] ] -= minFlow;
}
}
}
}
}
return sol;
}
void solve() {
for (int i = 0; i <= N; ++i) {
for (int j = 0; j <= N; ++j) {
flow[i][j] = cap[i][j] = 0;
}
}
scanf("%d%d", &N, &M);
for (int i = 1; i <= N; ++i) {
scanf("%d", &bani[ i ]);
}
for (int a = 1; a <= M; ++a) {
int p, x, y, c;
scanf("%d%d", &p, &cash[ a ]);
for (int i = 1; i <= p; ++i) {
scanf("%d", &x);
y = a + N;
cap[ x ][ y ] = cash[ a ];
G[ x ].push_back( y );
G[ y ].push_back( x );
// printf("++ %d->%d = %d\n", x, y, cap[x][y]);
}
}
for (int i = 1; i <= N; ++i) {
int x, y, c;
x = 0;
y = i;
c = bani[ i ];
cap[ x ][ y ] = c;
G[ x ].push_back( y );
G[ y ].push_back( x );
// printf("++ %d->%d = %d\n", x, y, cap[x][y]);
}
for (int i = 1; i <= M; ++i) {
int x, y, c;
x = i + N;
y = N + M + 1;
cap[ x ][ y ] = cash[ i ];
G[ x ].push_back( y );
G[ y ].push_back( x );
// printf("++ %d->%d = %d\n", x, y,cap[x][y]);
}
N = N + M + 1;
printf("%d\n", maxflow(0, N));
}
int main() {
freopen("tribut.in", "r", stdin);
freopen("tribut.out", "w", stdout);
int T;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}