Cod sursa(job #963582)

Utilizator matei_cChristescu Matei matei_c Data 17 iunie 2013 20:18:47
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.99 kb
#include<fstream>
#include<queue>
#include<vector>
using namespace std ;

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

#define maxn 601
const int inf = 1000000 ;

int N, M, E, sursa, destinatie ;
int muchie[maxn][maxn], cost[maxn][maxn], cmin[maxn] ;
vector<int> graf[maxn] ;

queue<int> coada ;
bool incoada[maxn] ;
int cap[maxn][maxn], flux[maxn][maxn], tata[maxn] ;

int sol, rez ;
bool ok ;

void citire_si_initializare()
{
    fin >> N >> M >> E ;
    sursa = 0 ;
    destinatie = N + M + 1 ;

    for(int i = 1; i <= E; ++i )
    {
        int x, y, c ;
        fin >> x >> y >> c ;

        muchie[x][ y + N ] = i ;

        cost[x][ y + N ] = c ;
        cost[ y + N ][x] = -c ;
        cap[x][ y + N ] = 1 ;

        graf[x].push_back( y + N ) ;
        graf[ y + N ].push_back(x) ;
    }

    for(int i = 1; i <= N; ++i )
    {
        graf[sursa].push_back(i) ;
        graf[i].push_back(sursa) ;
        cap[sursa][i] = 1 ;
    }

    for(int i = 1; i <= M; ++i )
    {
        graf[ N + i ].push_back(destinatie) ;
        graf[destinatie].push_back( N + i ) ;
        cap[ N + i ][destinatie] = 1 ;
    }
}

void init()
{
    for(int i = sursa; i <= destinatie; ++i )
        cmin[i] = inf ;
    cmin[sursa] = 0 ;

    coada.push(sursa) ;
    incoada[sursa] = true ;
}

int BellmanFord()
{
    init() ;

    while( coada.empty() == false )
    {
        int nod = coada.front() ;
        incoada[nod] = false ;
        coada.pop() ;

        for(size_t i = 0; i < graf[nod].size(); ++i )
        {
            int vecin = graf[nod][i] ;

            if( cap[nod][vecin] > flux[nod][vecin] && cmin[vecin] > cmin[nod] + cost[nod][vecin] )
            {
                cmin[vecin] = cmin[nod] + cost[nod][vecin] ;
                tata[vecin] = nod ;

                if( incoada[vecin] == false)
                {
                    coada.push(vecin) ;
                    incoada[vecin] = true ;
                }
            }
        }
    }

    if( cmin[destinatie] != inf )
    {
        ok = true ;
        int fluxmin = inf ;

        int nod = destinatie ;
        while( nod != sursa )
        {
            fluxmin = min( fluxmin, cap[ tata[nod] ][nod] - flux[ tata[nod] ][nod] ) ;
            nod = tata[nod] ;
        }

        nod = destinatie ;
        while( nod != sursa )
        {
            flux[ tata[nod] ][nod] += fluxmin ;
            flux[nod][ tata[nod] ] -= fluxmin ;
            nod = tata[nod] ;
        }

        sol += fluxmin ;

        return fluxmin * cmin[destinatie] ;
    }

    return 0 ;
}

int main()
{
    citire_si_initializare() ;

    ok = true ;
    while( ok == true )
    {
        ok = false ;
        rez += BellmanFord() ;
    }

    fout << sol << " " << rez << "\n" ;

    for(int i = 1; i <= N; ++i )
        for(int j = 1; j <= M; ++j )
            if( flux[i][ j + N ] )
                fout << muchie[i][ j + N ] << " " ;

    return 0 ;
}