Pagini recente » Cod sursa (job #2848038) | Cod sursa (job #22703) | Cod sursa (job #1870655) | Cod sursa (job #2866185) | Cod sursa (job #1709106)
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int nmax = 210, inf = 0x3f3f3f3f;
int t, n, m, x, cap[nmax][nmax], flow[nmax][nmax], father[nmax];
vector<int> g[nmax];
int source, sink;
bool bfs()
{
for (int i = source; i <= sink; ++ i)
father[i] = -1;
queue<int> q;
q.push(source);
while (!q.empty())
{
int node = q.front();
q.pop();
if (node == sink) break;
for (int i = 0; i < g[node].size(); ++ i)
{
int vec = g[node][i];
if (father[vec] == -1 && cap[node][vec] > flow[node][vec])
{
father[vec] = node;
q.push(vec);
}
}
}
return father[sink] != -1;
}
int maxFlow()
{
int fl = 0;
while (bfs())
{
for (int i = 0; i < g[sink].size(); ++ i)
{
int vec = g[sink][i];
if (father[vec] != -1 && cap[vec][sink] != flow[vec][sink])
{
father[sink] = vec;
int minfl = inf;
for (int node = sink; node != source; node = father[node])
minfl = min(minfl, cap[father[node]][node] - flow[father[node]][node]);
for (int node = sink; node != source; node = father[node])
{
flow[father[node]][node] += minfl;
flow[node][father[node]] -= minfl;
}
fl += minfl;
}
}
}
return fl;
}
int main()
{
freopen("tribut.in", "r", stdin);
freopen("tribut.out", "w", stdout);
scanf("%i", &t);
for (; t; -- t)
{
for (int i = 0; i < nmax; ++ i)
{
father[i] = -1;
g[i].clear();
for (int j = 0; j < nmax; ++ j)
cap[i][j] = flow[i][j] = 0;
}
scanf("%i %i", &n, &m);
source = 0;
sink = n + m + 1;
for (int i = 1; i <= n; ++ i)
{
scanf("%i", &x);
g[m + i].push_back(sink);
g[sink].push_back(m + i);
cap[m + i][sink] = x;
}
for (int i = 1; i <= m; ++ i)
{
int p, mxtr;
scanf("%i %i", &p, &mxtr);
g[source].push_back(i);
g[i].push_back(source);
cap[source][i] = mxtr;
for (int j = 1; j <= p; ++ j)
{
scanf("%i", &x);
g[i].push_back(m + x);
g[m + x].push_back(i);
cap[i][m + x] = inf;
}
}
printf("%d\n", maxFlow());
}
}