Cod sursa(job #1164730)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 2 aprilie 2014 11:50:51
Problema Algola Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.64 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

const int Nmax = 5000;
const int inf = 1e9;

vector <int> G[Nmax];
vector < pair<int,int> > GG[Nmax];
int dad[Nmax], vis[Nmax], Q[Nmax];
int C[Nmax][Nmax], F[Nmax][Nmax];

int N, M, S, D, DIM;

int BFS( int S, int D )
{
    for ( int i = 0; i <= DIM; ++i )
    {
        dad[i] = 0;
        vis[i] = 0;
    }

    int st, dr;
    Q[st = dr = 1] = S;
    vis[S] = 1;

    while ( st <= dr )
    {
        int nod = Q[ st++ ];

        for ( auto x: G[nod] )
        {
            if ( !vis[x] && C[nod][x] > F[nod][x] )
            {
                vis[x] = 1;
                dad[x] = nod;
                Q[ ++dr ] = x;

                if ( x == D )
                        return 1;
            }
        }
    }

    return 0;
}

int Edmonds_Karp( int S, int D )
{
    int flow = 0, fmin;

    while ( BFS( S, D ) )
    {
        for ( auto son: G[D] )
        {
            if ( !vis[son] || F[son][D] >= C[son][D] ) continue;

            dad[D] = son;
            fmin = inf;

            for ( int nod = D; nod != S; nod = dad[ nod ] )
                    fmin = min( fmin, C[ dad[nod] ][nod] - F[ dad[nod] ][nod] );

            if ( !fmin ) continue;

            for ( int nod = D; nod != S; nod = dad[ nod ] )
            {
                F[ dad[nod] ][nod] += fmin;
                F[nod][ dad[nod] ] -= fmin;
            }

            flow += fmin;
        }
    }

    return flow;
}

void add_edge( int x, int y, int cap )
{
    G[x].push_back( y );
    G[y].push_back( x );

    C[x][y] = cap;
}

void build_network( int T )
{
    D = T * N + 1;
    DIM = D;

    for ( int i = 1; i <= N; ++i )
    {
        add_edge( N * ( T - 1 ) + i, N * T + i, inf );
    }

    for ( int i = 1; i <= N; ++i )
    {
        for ( auto x: GG[i] )
        {
            add_edge( N * ( T - 1 ) + i, N * T + x.first, x.second );
        }
    }
}

int main()
{
    ifstream f("algola.in");
    ofstream g("algola.out");

    int totalSum = 0;

    f >> N >> M;

    S = 0;

    for ( int i = 1, c; i <= N; ++i )
    {
        f >> c;

        add_edge( S, i, c );
        totalSum += c;
    }

    for ( int i = 1, a, b, c; i <= M; ++i )
    {
        f >> a >> b >> c;

        GG[a].push_back( pair<int,int>( b, c ) );
        GG[b].push_back( pair<int,int>( a, c ) );
    }

    int sol = 0;
    int t = 0;

    while ( sol < totalSum )
    {
        build_network( t + 1 );
        sol += Edmonds_Karp( S, D );
        t++;
    }

    g << t << "\n";

    return 0;
}