Cod sursa(job #1800364)

Utilizator felixiPuscasu Felix felixi Data 7 noiembrie 2016 18:34:40
Problema Cc Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

ifstream in("cc.in");
ofstream out("cc.out");

const int NMAX = 100;
const int INF  = (1 << 30);

vector <int> G[NMAX+2], GP[NMAX+2];
int cost[NMAX+2][NMAX+2];
int tt[NMAX+2], C[NMAX+2][NMAX+2], F[NMAX+2][NMAX+2];
priority_queue< pair<int,int>, vector< pair<int,int> >, greater< pair<int,int> > > H;
bool viz[NMAX+2];
int d[NMAX+2], N;

bool DIJKSTRA( int st, int fn ) {
    viz[st] = 1;
    H.push( make_pair( 0, st ) );
    while( !H.empty() ) {
        pair<int,int> pp = H.top();
        H.pop();

        int nod = pp.second;
        viz[nod] = 1;
        for( int i = 0;  i < (int)G[nod].size();  ++i ) {
            int x = G[nod][i];
            if( C[nod][x] - F[nod][x] <= 0 ) continue;
            if( !viz[x] || d[nod] + cost[nod][x] < d[x] ) {
                d[x] = d[nod] + cost[nod][x];
                tt[ x ] = nod;
                H.push( make_pair( d[x], x ) );
            }
        }
    }
    return viz[fn];
}

int MAX_FLOW_MIN_COST( int st, int fn ) {
    int ans = 0;
    while( DIJKSTRA(st, fn) ) {
        for( int i = 0;  i < (int)G[fn].size();  ++i ) {
            int x = G[fn][i], special = x;
            if( !viz[x] || F[x][fn] >= C[x][fn] ) continue;

            int min_flow = C[x][fn] - F[x][fn];
            for( ;  x != st;  x = tt[x] ) {
                min_flow = min(min_flow, C[ tt[x] ][ x ] - F[ tt[x] ][ x ] );
            }

            x = special;

            int tot_cost = cost[ x ][ fn ] * (C[x][fn] - F[x][fn]);
            F[ x ][ fn ] += min_flow;
            F[ fn ][ x ] -= min_flow;
            for( ;  x != st;  x = tt[x] ) {
                tot_cost += cost[ tt[x] ][ x ] * (C[ tt[x] ][ x ] - F[ tt[x] ][ x ]);

                F[ tt[x] ][ x ] += min_flow;
                F[ x ][ tt[x] ] -= min_flow;
            }

            ///ans += tot_cost;
        }

        memset( viz, 0, sizeof(viz) );
        memset( tt, 0, sizeof(tt) );
        memset( d, 0, sizeof(d) );

    }

    for( int i = 0;  i <= 2*N;  ++i ) {
        for( int j = 0;  j < (int)G[i].size();  ++j ) {
            int x = G[i][j];
            ans += F[ i ][ x ]* cost[ i ][ x ];
        }
    }

    return ans;
}

int main()
{
    in >> N;
    for( int i = 1;  i <= N; ++i ) {
        for( int j = 1;  j <= N;  ++j ) {
            int x;
            in >> x;
            G[i].push_back( N+j );
            G[ N+j ].push_back( i );
            cost[i][N+j] = x;
            C[i][N+j] = 1;
        }
    }
    int START = 0, FINISH = 2*N+1;
    for( int i = 1;  i <= N;  ++i ) {
        G[START].push_back( i );
        G[i].push_back( START );
        cost[START][i] = 0;
        C[START][i] = 1;

        G[N+i].push_back( FINISH );
        G[FINISH].push_back( N+i );
        cost[ N+i ][ FINISH ] = 0;
        C[ N+i ][FINISH] = 1;

    }
    out << MAX_FLOW_MIN_COST(START, FINISH);
    return 0;
}