Cod sursa(job #6265)

Utilizator rusRus Sergiu rus Data 18 ianuarie 2007 16:55:52
Problema Cc Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.12 kb
#include <stdio.h>
#define MAX 104


typedef struct nod
{
    int x;
    nod *adr_urm;
}*pnod;

pnod l[MAX];

int n, sol;
int d[MAX], t[MAX];
int c[MAX][MAX], cost[MAX][MAX], f[MAX][MAX];


void citire ();
void add ( int i, int j );
void solve ();
void drum ();
void afisare ();

int bellmand ();
int minimizeaza ();

inline int abs ( int i )
{
    if ( i < 0 )
        return -i;
    return i;
}


int main ()
{
    freopen ( "cc.in", "r", stdin );
    freopen ( "cc.out", "w", stdout );

    citire ();
    solve ();
    afisare ();

    return 0;
}

void citire ()
{
    int i, j, x;

    scanf ( "%d", &n );
    for ( i = 1; i <= n; i++ )
    {
        for ( j = 1; j <= n; j++ )
        {
            scanf ( "%d", &x );
            add ( i, j + n );
            add ( j + n, i );
            c[i][j + n] = 1;
            cost[i][j + n] = cost[j + n][i] = x;
        
//            printf ( "%d ", x );
        }
//       printf ("\n" );
    }

    for ( i = 1; i <= n; i++ )
    {
        add ( 0, i );
        add ( i, 0 );
        c[0][i] = 1;
        cost[0][i] = 0;
    }

    for ( i = n + 1; i <= n + n; i++ )
    {
        add ( i, n + n + 1 );
        add ( n + n + 1, i );
        c[i][n + n + 1] = 1;
    }
    //pnod p;
    //for ( p = l[n + n + 1]; p; p = p->adr_urm )
        //printf ( "%d ", p->x );
}

void add ( int i, int j )
{
    pnod p = new nod;

    p->x = j;
    p->adr_urm = l[i];
    l[i] = p;
}

void solve ()
{
    while ( bellmand () )
        drum ();
}

int bellmand ()
{
    int i, j;

    for ( i = 0; i <= n + n + 1; i++ )
    {
        d[i] = 2000000;
        t[i] = 0;
    }

    d[0] = 0;
    
    for ( i = 0; i < n + n + 1; i++ )
        if ( !minimizeaza () )
            break;

    if ( d[n + n + 1]==2000000 )
        return 0;
    return 1;
}

int minimizeaza ()
{
    int i, j, ok;
    pnod p;

    ok = 0;
    for ( i = 0; i <= n + n + 1; i++ )
        for ( p = l[i]; p; p = p->adr_urm )
        {
	    j = p->x;

            if ( c[i][j] > f[i][j] )
                if ( d[j] > d[i] + cost[i][j] )
                {
                    d[j] = d[i] + cost[i][j];
                    t[j] = i;
                    ok = 1;
                }
            if ( f[j][i] ) 
                if ( d[j] > d[i] - cost[i][j] )
                {
                    d[j] = d[i] - cost[i][j];
                    t[j] = -i;
                    ok = 1;
                }
        }
    return ok;
}

void drum ()
{
    int i, j;

    i = n + n + 1;
    while ( i )
    {
        j = abs ( t[i] );

        if ( t[i] >= 0 )
            f[j][i] += 1;
        else
            f[i][j] -= 1;
        i = j;
    }
}                    
              
void afisare ()
{
    int i, j;

    for ( i = 1; i <= n; i++ )
        for ( j = n + 1; j <= n + n; j++ )
            if ( f[i][j] )
            {
                //printf ( "%d %d\n", i, j - n );
                sol += cost[i][j];
                break;
            }

    printf ( "%d", sol );
}