Cod sursa(job #8215)

Utilizator rusRus Sergiu rus Data 23 ianuarie 2007 22:34:19
Problema Critice Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.25 kb
#include <stdio.h>
#define MAX 1001

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

pnod l[MAX], l1[MAX];

int inds, n, m, nrr, sol, nra, ind, rad;
int q[MAX], s[MAX], cr[MAX], t[MAX], a[MAX * 10], b[MAX * 10], cc[MAX* 10], r[MAX * 10], ss[MAX], sd[MAX], rt[MAX * 10];
int c[MAX][MAX], f[MAX][MAX], o[MAX][MAX];


void citire ();
void add ( int i, int j, int y );
void add1 ( int i, int j, int y );
void solve ();
void drum ();
void dfs ( int i );
void dfd ( int i );
void qsort ( int i, int j );
void afisare ();

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

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

    citire ();
    solve ();

    return 0;
}

void citire ()
{
    int i, x, y, cost;

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

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

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

void solve ()
{
    int i, j, x, y, nr;
    pnod p;

    inds = 1;
    for ( i = 1; flow (); i++ )
    {
        inds++;
        drum ();
        sol += cr[n];
    }

    for ( i = 1; i <= n; i++ )
        for ( p = l[i]; p; p = p->adr_urm )
            if ( c[i][p->x] != f[i][p->x] )
            {
                add1 ( i, p->x, 1 );   
                add1 ( p->x, i, 1 );
//                printf ( "%d %d\n", i, p->x );
            }
            else
            {
                nra++;      
//                add1 ( i, p->x, -1 );
//                add1 ( p->x, i, - 1);

                o[i][p->x] = o[p->x][i] = -1; 
                a[nra] = i;
                b[nra] = p->x;
                cc[nra] = p->y;
            }
//    printf ( "\n" );

    
    dfs ( 1 );
    dfd ( n );
    ind = 1;
    for ( i = 1; i <= m; i++ )    
    {
        x = a[i];
        y = b[i];
    
        nr = 0;
        if ( (ss[x] == 1 && sd[y] == 1) || (ss[y] == 1 && sd[x] == 1 ) )
            nr = 2;
   
        if ( nr == 2 )
        {
            nrr++;
            rt[cc[i]] = 1;
        }
        //    printf ( "%d %d\n", x, y );
    }

//    for ( i = 1; i <= n; i++ )
//        printf ( "%d ", sd[i] );
//    printf ( "\n" );
    //qsort ( 1, nrr );   
    printf ( "%d\n", nrr );
    for ( i = 1; i <= m; i++ )
        if ( rt[i] )
            printf ( "%d\n", i );

}

void dfs ( int nod )
{
    pnod p;

    ss[nod] = 1;
    for ( p = l1[nod]; p; p = p->adr_urm )
        if ( !ss[p->x] && o[nod][p->x] != -1)
            dfs ( p->x );    
}

void dfd ( int nod )
{
    pnod p;

    sd[nod] = 1;
    for ( p = l1[nod]; p; p = p->adr_urm )
        if ( !sd[p->x] &&  o[nod][p->x] != -1)
            dfd ( p->x );    
}


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

    p->x = j;
    p->y = ind;
    p->adr_urm = l1[i];
    l1[i] = p;
}
    
int flow ()
{
    int prim, ultim, i, j;
    pnod p;

    for ( i = 1; i <= n; i++ )
    //    s[i] = t[i] = q[i] = cr[i] = 0;
        cr[i] = 0;

    prim = ultim = 1;
    q[1] = 1;
    s[1] = inds;
    t[1] = 0;
    cr[1] = 32000;    

    while ( prim <= ultim )
    {
        i = q[prim];
        for ( p = l[i]; p; p = p->adr_urm )
            if ( s[p->x] != inds )
            {
                j = p->x;
                
                if ( c[i][j] > f[i][j] )
                {   
                    if ( c[i][j] - f[i][j] < cr[i] )
                        cr[j] = c[i][j] - f[i][j];
                    else
                        cr[j] = cr[i];

                    s[j] = inds;
                    t[j] = i;
                    q[++ultim] = j;
                    if ( j == n )
                        return 1;
                }
                if ( f[j][i] > 0 )
                {
                    if ( cr[i] < f[j][i] )
                        cr[j] = cr[i];
                    else
                        cr[j] = f[j][i];

                    s[j] = inds;
                    t[j] = -i;
                    q[++ultim] = j;

                    if ( j == n )
                        return 1;
                }
            }
        prim++;
    }
    return 0;
}

void drum ()
{
    int i, j;

    i = n;

    while ( i )
    {   
        j = abs ( t[i] );
    
        if ( t[i] > 0 )
            f[j][i] += cr[n];
        else
            f[i][j] -= cr[n];
        i = j;
    }
}
                
void qsort ( int prim, int ultim )
{
    int i, j, mij, aux;

    i = prim;
    j = ultim;
    mij = r[(i + j) / 2];

    do
    {
        while ( r[i] < mij )
            i++;
        while ( r[j] > mij )
            j--;

        if ( i <= j )
        {
            aux = r[i];
            r[i] = r[j];    
            r[j] = aux;
            i++;
            j--;
        }
    }
    while ( i < j );

    if ( i < ultim )
        qsort ( i, ultim );
    if ( j > prim )
        qsort ( prim, j );
}