Cod sursa(job #882367)

Utilizator veleanduAlex Velea veleandu Data 19 februarie 2013 01:42:01
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.49 kb
#include <cassert>
#include <cstdio>
#include <ctime>
#include <cstdlib>
 
#include <algorithm>
#include <iostream>
#include <vector>
 
using namespace std;
 
#define max_n 1005
#define max_m 10005
#define FORIT( it, v ) for( typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it )
#define pb push_back
 
struct edge{
    int a,b,c,f;
    edge(){
        a=b=c=f=0;
    }
    edge( int x, int y, int z ){
        a=x;
        b=y;
        c=z;
        f=0;
    }
    int length( int p ){
        if ( b == p ){
            return c-f;
        }
        return c+f;
    }
    void increase( int p, int val ){
        if ( p == b ){
            f+=val;
        }
        else{
            f-=val;
        }
    }
    int other( int nod ){
        return a+b-nod;
    }
    void debug( ){
        cerr<<a<<"\t"<<b<<"\t"<<c<<"\t"<<f<<"\n";
        cerr<<length(b)<<"\t"<<length(a)<<"\n\n";
    }
} Edge[ max_m ];
 
vector<int> Vertex[ max_n ], Rez;
int Father[ max_n ], Bfs[ max_n ];
int n,m,i,a,b,c,maxflow;
bool Viz[ 3 ][ max_n ];
 
bool bfs (){
    int nod,ind,dr,next,last;
    edge mu;
    dr=1;
    Bfs[1]=1;
    while ( dr ){
        if ( Father[ n ] )
            break;
        ind = rand()%dr;
        ind++;
        nod = Bfs[ ind ];
        Bfs[ ind ] = Bfs[ dr-- ];
        FORIT( it, Vertex[ nod ] ){
            mu = Edge[ *it ];
            next = mu.other( nod );
            if ( !Father[ next ] && mu.length( next ) > 0 ){
                Father[ next ] = *it;
                Bfs[ ++dr ] = next;
            }
        }
    }
    if ( Father[ n ] ){
        int val = 0x3f3f3f3f;
        nod = n;
        while ( nod != 1 ){
            mu = Edge[ Father[ nod ] ];
            last = mu.other( nod );
            val = min ( val, mu.length( nod ) );
            nod = last;
        }
        nod = n;
        while ( nod != 1 ){
            last = Edge[ Father[ nod ] ].other( nod );
            Edge[ Father[ nod ] ].increase( nod, val );
            nod = last;
        }
        maxflow += val;
        return 1;
    }
    else{
        return 0;
    }
}
 
void solve ( int nod, int color ){
    int st,dr,l;
    edge mu;
    st = dr = 1;
    Bfs[ 1 ] = nod;
    Viz[ color ][ nod ] = 1;
    while ( st <= dr ){
        nod = Bfs[ st++ ];
        FORIT( it, Vertex[ nod ] ){
            mu = Edge[ *it ];
            if ( color == 1 )
                l = mu.length( mu.other( nod ) );
            else
                l = mu.length( nod );
            if( !Viz[ color ][ mu.other( nod ) ] && l != 0 ){
                Bfs[ ++dr ] = mu.other( nod );
                Viz[ color ][ mu.other( nod ) ] = 1;
            }
        }
    }
    return ;
}
int main(){
    srand( time(NULL) );
 
    freopen("critice.in","r",stdin);
    freopen("critice.out","w",stdout);
 
    scanf ("%d%d", &n, &m );
    for ( i=1; i<=m; ++i ){
        scanf("%d%d%d", &a, &b, &c );
        Edge[ i ] = edge( a,b,c ); 
        Vertex[ a ].pb( i );
        Vertex[ b ].pb( i );
    }
    Father[ 1 ] = 1;
    while ( bfs () ){
        for ( i=2; i<=n; ++i ){
            Father[ i ] = 0;
        }
    }

    solve ( 1, 1 );
    solve ( n, 2 );
 
    edge mu; 
    for ( i=1; i<=n; ++i ){
        FORIT ( it, Vertex[ i ] ){
            mu = Edge[ *it ];
            if ( Viz[ 1 ][ i ] == 1 && Viz[ 2 ][ mu.other( i ) ] == 1 )
                Rez.pb( *it );
        }
    }
    sort( Rez.begin(), Rez.end() );
    Rez.resize( unique( Rez.begin(), Rez.end() ) - Rez.begin() );
 
    printf("%d\n",Rez.size());
    FORIT( it, Rez ){
        printf("%d\n",*it);
    }
    return 0;
}