Cod sursa(job #1709106)

Utilizator team_nameUPB Banu Popa Visan team_name Data 28 mai 2016 10:55:19
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.62 kb
#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());
    }
}