Pagini recente » Rezultatele filtrării | Borderou de evaluare (job #2710796) | Rezultatele filtrării | Cod sursa (job #2490559) | Cod sursa (job #1709723)
#include <cstdio>
#include <vector>
#include <cstring>
#define INF 100000000
using namespace std;
int n, m;
int co[400];
vector<int> nod[205];
int Fmax[205][205];
int flux[205][205];
bool viz[205];
int ant[205];
int F;
bool bfs()
{
int inc = 1, sf = 1;
co[inc] = 0;
memset(viz, 0, sizeof(viz));
viz[0] = 1;
while(inc <= sf)
{
int poz = co[inc];
inc ++;
if(poz == n + m + 1)
return 1;
for(int i = 0; i < nod[poz].size(); i ++)
if(!viz[nod[poz][i]] && flux[poz][nod[poz][i]] < Fmax[poz][nod[poz][i]])
{
viz[nod[poz][i]] = 1;
ant[nod[poz][i]] = poz;
co[++sf] = nod[poz][i];
}
}
return 0;
}
int main()
{
int t, tribut;
freopen("tribut.in", "r", stdin);
freopen("tribut.out", "w", stdout);
scanf("%d", &t);
while(t --)
{
scanf("%d%d", &n, &m);
memset(Fmax, 0, sizeof(Fmax));
memset(flux, 0, sizeof(flux));
F = 0;
for(int i = 1; i <= n; i ++)
{
scanf("%d", &Fmax[0][i]);
nod[0].push_back(i);
nod[i].push_back(0);
}
int nr, tara;
for(int i = 1; i <= m; i ++)
{
scanf("%d%d", &nr, &tribut);
for(int j = 1; j <= nr; j ++)
{
scanf("%d", &tara);
nod[tara].push_back(n + i);
nod[n + i].push_back(tara);
Fmax[tara][n + i] = Fmax[0][tara];
}
nod[n + i].push_back(n + m + 1);
nod[n + m + 1].push_back(n + i);
Fmax[n + i][n + m + 1] = tribut;
}
while(bfs())
{
for(int i = 0; i < nod[n + m + 1].size(); i ++)
if(viz[nod[n + m + 1][i]] && flux[n + m + 1][nod[n + m + 1][i]] < Fmax[nod[n + m + 1][i]][n + m + 1])
{
int j = n + m + 1;
ant[n + m + 1] = nod[n + m + 1][i];
int fmin = INF;
while(j != 0)
{
fmin = min(fmin, Fmax[ant[j]][j] - flux[ant[j]][j]);
j = ant[j];
}
if(fmin != 0)
{
j = n + m + 1;
while(j != 0)
{
flux[ant[j]][j] += fmin;
flux[j][ant[j]] -= fmin;
j = ant[j];
}
F += fmin;
}
}
}
printf("%d\n", F);
for(int i = 0; i <= n + m + 1; i ++)
nod[i].clear();
}
return 0;
}