Cod sursa(job #1709557)

Utilizator UBB_Craciun_Griza_PuscasUBB ATeamHasNoName UBB_Craciun_Griza_Puscas Data 28 mai 2016 12:51:12
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 3.33 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <cstring>
using namespace std;

ifstream fin("tribut.in");
ofstream fout("tribut.out");

const int MAXN = 210;

int n, m, cap[MAXN], curNod = 0, last[MAXN], lastM[MAXN], used[MAXN];

vector<pair<int, int> > muchii;
vector<pair<int, int> > noduri[205];

int get_path() {
    queue<int> q;

    memset(used, 0, sizeof(int) * MAXN);

    q.push(0);

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

        //cout << nod << "\n";

        used[nod] = 1;

        if (nod == n + m + 1)
            return 1;

        for (int i = 0; i < noduri[nod].size(); ++i) {
            int node = noduri[nod][i].second;
            int muchie = noduri[nod][i].first;

            if (!used[node]) {
                if (muchii[muchie].first != muchii[muchie].second) {
                    used[node] = 1;
                    last[node] = nod;
                    lastM[node] = muchie;
                    q.push(node);
                }
            }
        }
    }
    return 0;

}

int main()
{
    int t;
    fin >> t;

    for(; t; --t) {
        curNod = 0;
        muchii.clear();
        for (int i = 0; i <= n + m + 1; ++i)
            noduri[i].clear();
        //vezi initializari
        fin >> n >> m;

        for (int i = 1; i <= n; ++i)
            fin >> cap[i];

        for (int i = 1; i <= n; ++i) {
            ++curNod;

            muchii.push_back(make_pair(cap[i], 0));
            muchii.push_back(make_pair(-cap[i], -cap[i])); //vezi

            noduri[0].push_back(make_pair(muchii.size() - 2, curNod));
            noduri[curNod].push_back(make_pair(muchii.size() - 1, 0));
        }

        for (int i = 1; i <= m; ++i) {
            int nr, p;
            fin >> nr >> p;

            curNod++;
            muchii.push_back(make_pair(p, 0));
            noduri[curNod].push_back(make_pair(muchii.size() - 1, n + m + 1));
            muchii.push_back(make_pair(-p, -p));
            noduri[n + m + 1].push_back(make_pair(muchii.size() - 1, curNod));

            for (int j = 1; j <= nr; ++j) {
                int k;
                fin >> k;
                muchii.push_back(make_pair(cap[k], 0));
                noduri[k].push_back(make_pair(muchii.size() - 1, curNod));
                muchii.push_back(make_pair(-cap[k], -cap[k]));
                noduri[curNod].push_back(make_pair(muchii.size() - 1, k));

            }
        }

        ++curNod;

        int sumFlux = 0;

        while(get_path()) {


            int maxFlux = 1 << 30;

            int nod = n + m + 1;

            while (nod != 0) {

                //cout<<nod <<" ";
                maxFlux = min(maxFlux, abs(muchii[lastM[nod]].first - muchii[lastM[nod]].second));
                nod = last[nod];
            }

            //cout << "\n" << maxFlux << "\n";

            sumFlux += maxFlux;

            nod = n + m + 1;

            while (nod != 0) {
                int muc = lastM[nod];
                if (muchii[muc].first < 0) {
                    muchii[muc].second -= maxFlux;
                    muchii[muc - 1].second -= maxFlux;
                }
                else {
                    muchii[muc].second += maxFlux;
                    muchii[muc + 1].second += maxFlux;
                }
                nod = last[nod];
            }
        }
        fout << sumFlux << "\n";

    }


    return 0;
}