Cod sursa(job #1709723)

Utilizator liisLIIS-Horia-Vlad-Denis liis Data 28 mai 2016 13:37:30
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.83 kb
#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;
}