Cod sursa(job #1709304)

Utilizator oldscotchUPB Old Scotch oldscotch Data 28 mai 2016 11:44:10
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.15 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int NMAX = 215;
const int INF = 0x3f3f3f3f;
int T, N, M, F[NMAX][NMAX], C[NMAX][NMAX], src, dst;
int par[NMAX];
bool visited[NMAX];

vector<int> G[NMAX];

void addEdge(int from, int to, int cap)
{

    C[from][to] = cap;
    G[from].push_back(to);
    G[to].push_back(from);
}

void read()
{
    scanf("%d%d", &N, &M);
    src = 0;
    dst = N + M + 1;

    int x;
    for (int i = 1; i <= N; i++)
    {
        scanf("%d", &x);
        addEdge(src, i, x);
    }
    int no, idx;
    for (int i = 1; i <= M; i++)
    {
        scanf("%d%d", &no, &x);
        addEdge(N + i, dst, x);
        for (int j = 1; j <= no; j++)
        {
            scanf("%d", &x);
            addEdge(x, N + i, INF);
        }
    }
}

void clear()
{
    memset(F, 0, sizeof(F));
    memset(C, 0, sizeof(C));
    for (int i = src; i <= dst; i++)
    {
        G[i].clear();
    }
}

int BF()
{
    queue<int> Q;
    memset(visited, false, sizeof(visited));
    Q.push(src);
    visited[src] = true;

    while (!Q.empty())
    {
        int node = Q.front();
        Q.pop();

        for (auto& x: G[node])
        {
            if (C[node][x] - F[node][x] > 0 && !visited[x])
            {
                visited[x] = true;
                Q.push(x);
                par[x] = node;
            }
        }
    }
    return visited[dst];
}

void solve()
{
    int result = 0;
    while (BF())
    {
        int fmin = INF;
        for (int node = dst; node != src; node = par[node])
        {
            fmin = min(fmin, C[par[node]][node] - F[par[node]][node]);
        }

        for (int node = dst; node != src; node = par[node])
        {
            F[par[node]][node] += fmin;
            F[node][par[node]] -= fmin;
        }
        result += fmin;
    }

    printf("%d\n", result);
}

int main()
{
    freopen("tribut.in", "r", stdin);
    freopen("tribut.out", "w", stdout);

    scanf("%d", &T);
    while (T--)
    {
        read();
        solve();
        clear();
    }

    return 0;
}