Cod sursa(job #1773507)

Utilizator radarobertRada Robert Gabriel radarobert Data 7 octombrie 2016 21:51:50
Problema Tribut Scor 0
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.55 kb
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

queue<int> q;
int c[210][210], f[210][210];
int parent[210];
bool vis[210];
const int dest = 205;
const int INF = 0x3f3f3f3f;

bool bfs(const int &n, const vector<int> *g)
{
    memset(vis, 0, sizeof(vis));
    q.push(0);
    vis[0] = true;

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

        for (const auto &it: g[node])
        {
            if (c[node][it] - f[node][it] > 0 && !vis[it])
            {
                parent[it] = node;
                q.push(it);
                vis[it] = true;
            }
        }
    }

    return vis[dest];
}

int main()
{
    freopen("tribut.in", "r", stdin);
    freopen("tribut.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int nr_tests;
    cin >> nr_tests;
    for (int test = 1; test <= nr_tests; test++)
    {
        int n, m;
        cin >> n >> m;

        vector<int> g[210];
        for (int i = 0; i <= n+m+1; i++)
        {
            memset(c[i], 0, sizeof(c[i]));
            memset(f[i], 0, sizeof(f[i]));
        }
        memset(c[dest], 0, sizeof(c[dest]));
        memset(f[dest], 0, sizeof(f[dest]));

        for (int i = 1; i <= n; i++)
        {
            cin >> c[0][i];
            g[0].push_back(i);
            g[i].push_back(0);
        }
        for (int i = 1; i <= m; i++)
        {
            int nr;
            cin >> nr;
            cin >> c[++n][dest];
            g[n].push_back(dest);
            g[dest].push_back(n);
            for (int j = 1; j <= nr; j++)
            {
                int x;
                cin >> x;
                g[x].push_back(n);
                g[n].push_back(x);
                c[x][n] = INF;
            }
        }
        int flow = 0;
        while (bfs(n, g))
        {
            for (const auto &it: g[dest])
            {
                int fmax = max(0, c[it][dest] - f[it][dest]);
                for (int i = it; i != 0; i = parent[i])
                    fmax = min(fmax, c[parent[i]][i] - f[parent[i]][i]);
                for (int i = it; i != 0; i = parent[i])
                {
                    f[parent[i]][i] += fmax;
                    f[i][parent[i]] -= fmax;
                }
                flow += fmax;
                f[it][dest] += flow;
                f[dest][it] -= flow;
            }
        }

        cout << flow << '\n';
    }

    return 0;
}