Cod sursa(job #990445)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 28 august 2013 12:47:14
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.2 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;

const int Nmax = 606;
const int oo = 0x3f3f3f3f;

typedef pair<int,int> node;

vector <int> G[Nmax];
int dist[Nmax], old_dist[Nmax], real_dist[Nmax];
int indice[Nmax][Nmax], C[Nmax][Nmax], F[Nmax][Nmax], Cost[Nmax][Nmax], viz[Nmax][Nmax];
int tata[Nmax];

priority_queue < node, vector <node>, greater<node> > heap;

int N, M, E;

int S, D;

ofstream g("cmcm.out");

void read()
{
    ifstream f("cmcm.in");

    f >> N >> M >> E;

    for ( int i = 1; i <= E; ++i )
    {
        int a, b, c;

        f >> a >> b >> c;

        a = a;
        b = b + N;

        G[a].push_back( b );
        G[b].push_back( a );

        C[a][b] = 1;

        Cost[a][b] = c;
        Cost[b][a] = -c;

        indice[a][b] = indice[b][a] = i;
    }

    f.close();
}

void construieste_graf()
{
    S = 0;
    D = N + M + 1;

    for ( int i = 1; i <= N; ++i )
    {
        G[S].push_back( i );
        G[i].push_back( S );

        C[S][i] = 1;

        Cost[S][i] = 0;
    }

    for ( int i = N + 1; i <= M + N; ++i )
    {
        G[D].push_back( i );
        G[i].push_back( D );

        C[i][D] = 1;

        Cost[i][D] = 0;
    }
}

inline bool Dijkstra()
{
    memset( dist, oo, sizeof( dist ) );

    dist[S] = real_dist[S] = 0;
    heap.push( node( 0, S ) );

    while( !heap.empty() )
    {
        int nod = heap.top().second;
        int val = heap.top().first;

        heap.pop();

        if( dist[nod] != val )
                continue;

        for( unsigned i = 0; i < G[nod].size(); i++ )
        {
            int son = G[nod][i];

            if( C[nod][son] > F[nod][son] )
            {
                int cost = dist[nod] + Cost[nod][son] + old_dist[nod] - old_dist[son];

                if( cost < dist[son] )
                {
                    tata[son] = nod;
                    dist[son] = cost;
                    real_dist[son] = real_dist[nod] + Cost[nod][son];

                    heap.push( node( dist[son], son ) );
                }
            }
        }
    }

    memcpy( old_dist, real_dist, sizeof( old_dist ) );

    return ( dist[D] != oo );
}

void Edmonds_Karp()
{
    int cost_f = 0, flow = 0;

    while( Dijkstra() )
    {
        int fmin = oo;

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

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

        cost_f += fmin * real_dist[D];
        flow += fmin;
    }

    cout << flow << " " << cost_f << "\n";
}

void print()
{
    for ( int i = 1; i <= N; ++i )
    {
        for ( unsigned j= 0; j < G[i].size(); ++j )
        {
            int son = G[i][j];

            if ( F[i][son] == 1 )
                    g << indice[i][son] << " ";
        }
    }

    g << "\n";

    g.close();
}

int main()
{
    read();
    construieste_graf();
    Edmonds_Karp();
    print();

    return 0;
}