Cod sursa(job #1709278)

Utilizator linia_intaiConstantinescu Iordache Ciobanu Noi cei din linia intai linia_intai Data 28 mai 2016 11:36:08
Problema Tribut Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.52 kb
#include <cstring>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAX_N = 300;

int N, F[MAX_N][MAX_N];
int C[MAX_N][MAX_N];
vector<int> G[MAX_N];
int p[MAX_N];

 bool is_path()
{
    for (int i = 0; i <= N; i += 1) {
        p[i] = -2;
    }
    queue<int> q;
    q.push(0);p[0]=-1;
    while(!q.empty())
    {
        if(q.front()==N)
        {
            q.pop();
            continue;
        }
        for(vector<int>::iterator it=G[q.front()].begin();it!=G[q.front()].end();it++)
            if(p[*it] == -2 && F[q.front()][*it]<C[q.front()][*it])
            {
                q.push(*it);
                p[*it]=q.front();
            }
        q.pop();
    }
    if(p[N] == -2)
        return false;
    return true;
}


int main() {
    ifstream cin("tribut.in");
    ofstream cout("tribut.out");
    int tests, n, m;
    for (cin >> tests; tests; -- tests) {
        cin >> n >> m;
        for (int i = 0; i <= n + m + 1; i += 1) {
            G[i].clear();
        }
        memset(F, 0, sizeof F);
        memset(C, 0, sizeof C);
        for (int i = 1; i <= n; ++ i) {
            cin >> C[0][i];
            G[0].push_back(i);
            G[i].push_back(0);
        }
        for (int sz, i = 1; i <= m; ++ i) {
            cin >> sz >> C[i + n][n + m + 1];
            G[i + n].push_back(n + m + 1);
            G[n + m + 1].push_back(i + n);
            for (int x, j = 1; j <= sz; j += 1) {
                cin >> x;
                C[x][i + n] = 1000000000;
                G[x].push_back(i + n);
                G[i + n].push_back(x);
            }
        }
        int total = 0; N = n + m + 1;
        while (is_path())
            for (vector<int>::iterator it=G[N].begin();it!=G[N].end();it++)
                if (F[*it][N] < C[*it][N] && p[*it] != -2) {
                    int u=*it,flux=C[*it][N]-F[*it][N];
                    while(u!=0)
                    {
                        flux=min(flux,C[p[u]][u]-F[p[u]][u]);
                        u=p[u];
                    }
                    u=*it;
                    F[*it][N]+=flux;
                    F[N][*it]-=flux;
                    while(u!=0)
                    {
                        F[p[u]][u]+=flux;
                        F[u][p[u]]-=flux;
                        u=p[u];
                    }
                    total+=flux;
                }
        cout << total << "\n";
    }
    return 0;
}