Cod sursa(job #134543)

Utilizator cos_minBondane Cosmin cos_min Data 11 februarie 2008 20:55:29
Problema Critice Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <stdio.h>
#include <fstream>
using namespace std;

#define in "critice.in"
#define out "critice.out"
#define dim 1001

int N, M;
int Q[dim], T[dim], R[dim*10], H[2][dim];
int Cap[dim][dim], Flux[dim][dim];
bool Sel[dim], S1[dim], S2[dim], S[dim][dim];

int BF();
void Augment();
void DF(int);

int main()
{
    int X, Y, C, K = 0;
    freopen(in,"r",stdin);
    freopen(out,"w",stdout);
    
    scanf("%d%d", &N, &M);
    for ( int i = 1; i <= M; i++ )
    {
        scanf("%d%d%d", &X, &Y, &C);
        Cap[X][Y] = Cap[Y][X] = C;
        H[0][i] = X, H[1][i] = Y;
    }
    
    while ( BF() ) Augment();
    
    DF(1);
    
    for ( int i = 1; i <= N; i++ ) 
        S2[i] = S1[i], S1[i] = 0;
    
    DF(N);
    
    for ( int i = 1; i <= M; i++ )
    {
        int nod1 = H[0][i], nod2 = H[1][i];
        
        if ( Cap[nod1][nod2] == Flux[nod1][nod2] )
        {
           if ( (S1[nod1]&S2[nod2]) || (S2[nod1]&S1[nod2]) ) K++, R[K] = i;
        }
        else
        {
            swap(nod1,nod2);
            if ( Cap[nod2][nod1] == Flux[nod1][nod2] )
               if ( (S1[nod1]&S2[nod2]) || (S2[nod1]&S1[nod2]) ) K++, R[K] = i;
        }
           
    }
    
    printf("%d\n", K);
    for ( int i = 1; i <= K; i++ )
        printf("%d\n", R[i]);
}

void DF(int nod)
{
     S1[nod] = 1;
     
     for ( int i = 1; i <= N; i++ )
         if ( !S1[i] && Cap[nod][i] > 0 && Flux[nod][i] != Cap[nod][i] && Flux[i][nod] != Cap[nod][i] ) DF(i);
}

int BF()
{
    memset(Sel,0,sizeof(Sel));
    int act, last;
    
    Q[act=last=1] = Sel[1] = 1;
    
    while ( act <= last )
    {
          int nod = Q[act];
          for ( int i = 1; i <= N; i++ )
              if ( Cap[nod][i] - Flux[nod][i] > 0 && !Sel[i] )
              {
                   last++;
                   Q[last] = i, Sel[i] = 1, T[i] = nod;
                   if ( i == N ) return 1;
              }
          
          act++;
    }
    
    return 0;
}

void Augment()
{
     int minim = (1<<21);
     
     for ( int i = N; i != 1; i = T[i] )
         if ( minim > Cap[T[i]][i] - Flux[T[i]][i] ) minim = Cap[T[i]][i] - Flux[T[i]][i];
     
     for ( int i = N; i != 1; i = T[i] )
         Flux[T[i]][i] += minim;
}