Cod sursa(job #82221)

Utilizator DastasIonescu Vlad Dastas Data 5 septembrie 2007 22:46:34
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <cstdio>

const int maxn = 204;
const int inf = 100000;

FILE *in = fopen("cc.in","r"), *out = fopen("cc.out","w");

struct info
{
    int cost, flux;
};

int n;
info a[maxn][maxn];
int f[maxn][maxn];

void read()
{
    fscanf(in, "%d", &n);

//    for ( int i = 0; i <= n + n + 1; ++i )
//        for ( int j = 0; j <= n + n + 1; ++j )
//            a[i][j].cost = 0, a[i][j].flux = 0;

    for ( int i = 1; i <= n; ++i )
        for ( int j = 1; j <= n; ++j )
        {
            fscanf(in, "%d", &a[i][j+n].cost);

            a[j+n][i].cost = -a[i][j+n].cost;
            a[i][j+n].flux = 1;
        }

    for ( int i = 1; i <= n; ++i )
        a[0][i].cost = 0, a[0][i].flux = 1;
    for ( int i = n+1; i < n+n+1; ++i )
        a[i][n+n+1].cost = 0, a[i][n+n+1].flux = 1;
}

int C[maxn*maxn];
int viz[maxn]; // viz[i] = 1 daca nodul i este in coada
int pred[maxn]; // pred[i] = predecesorul nodului i (pt reconstituire)
int cst[maxn]; // cst[i] = costul minim pana in nodul i
int BF()
{
    for ( int i = 0; i <= n+n+1; ++i )
        viz[i] = 0, cst[i] = inf;
    cst[0] = 0;
    int p = 0, u = 0;
    C[p] = 0;

    int ok = 0;

    while ( p <= u )
    {
        int x = C[p++];
        viz[x] = 0;

        for ( int i = 1; i <= n + n + 1; ++i )
            if ( f[x][i] < a[x][i].flux )
            {
                if ( i == n + n + 1 )
                    ok = 1;

                if ( cst[x] + a[x][i].cost < cst[i] )
                {
                    cst[i] = cst[x] + a[x][i].cost;
                    pred[i] = x;

                    if ( viz[i] == 0 )
                        C[++u] = i;
                }
            }
    }

    return ok;
}

inline int min(int x, int y)
{
    return x < y ? x : y;
}

int L[maxn];
int answ;
void flow()
{
    int lg;
    while ( BF() )
    {
        lg = 0;
        L[lg] = n + n + 1;
        int v = inf;

        while ( L[lg] != 0 )
        {
            ++lg;

            L[lg] = pred[ L[lg-1] ];

            v = min(v, a[ L[lg] ][ L[lg-1] ].flux - f[ L[lg] ][ L[lg-1] ]);
        }

        for ( int i = lg; i; --i )
        {
            f[ L[i] ][ L[i-1] ] += v;
            f[ L[i-1] ][ L[i] ] -= v;
        }
    }
}

int main()
{
    read();
    flow();

//    for ( int i = 1; i <= n; ++i )
//    {
//        for ( int j = n+1; j <= n + n; ++j )
//            printf("%d ", f[i][j]);
//        printf("\n");
//    }

    for ( int i = 1; i <= n; ++i )
        for ( int j = n+1; j <= n + n; ++j )
            if ( f[i][j] > 0 )
                answ += a[i][j].cost;

    fprintf(out, "%d\n", answ);

    return 0;
}