Cod sursa(job #213608)

Utilizator madmanjonesJones the one madmanjones Data 10 octombrie 2008 16:23:52
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <cstdlib>
#include <fstream>

using namespace std;

#define N 1001
#define M 10001

ifstream fin("critice.in");
ofstream fout("critice.out");

int n,m,c[N][N],f[N][N],T[N],gr[N],x[M],y[M],*G[N],Q[N],mark[N];

void citire()
{
     int i,a,b,cap;
     fin >> n >> m;
     for (i=1; i<=m; ++i)
     {
         fin >> a >> b >> cap;
         x[i] = a;
         y[i] = b;
         c[a][b] = cap;
         c[b][a] = cap;
         gr[a]++;
         gr[b]++;
     }
     for (i=1; i<=n; ++i)
     {
         G[i]=(int *) malloc((gr[i]+1) * sizeof(int));
         G[i][gr[i]]=-1;
         gr[i]=0;
     }

     for (i=1; i<=m; ++i)
     {
         G[x[i]][gr[x[i]]++]=y[i];
         G[y[i]][gr[y[i]]++]=x[i];
     }
}

int min(int a, int b)
{
    if (a<b)
        return a;
    else
        return b;
}

int bfs()
{
    int *p,cap,coada,nr,i;
    cap=coada=1;
    Q[cap]=1;
    for (i=2; i<=n; ++i) T[i]=-1;

    while (cap<=coada)
    {
        nr=Q[cap];
        p=G[nr];
        while (*p!=-1)
        {
            if (T[*p]==-1 && (c[nr][*p]-f[nr][*p])>0)
            {
                T[*p]=nr;
                coada++;
                Q[coada]=*p;
                if (*p==n)
                    return 1;
            }
            ++p;
        }
        ++cap;
    }
    return 0;
}

void bf1(int start, int val)
{
    int cap,coada,nr,*p;
    cap=coada=1;
    Q[cap]=start;
    mark[start]=val;
    while (cap<=coada)
    {
        nr=Q[cap];
        p=G[nr];
        while (*p!=-1)
        {
            if (mark[*p]!=val && (c[nr][*p]-f[nr][*p])>0)
            {
                mark[*p] = val;
                coada++;
                Q[coada] = *p;
            }
            ++p;
        }
        ++cap;
    }
}

void bf2(int start, int val)
{
    int cap,coada,nr,*p;
    cap=coada=1;
    Q[cap]=start;
    mark[start]=val;
    while (cap<=coada)
    {
        nr=Q[cap];
        p=G[nr];
        while (*p!=-1)
        {
            if (mark[*p]!=val && (c[*p][nr]-f[*p][nr])>0)
            {
                mark[*p]=val;
                coada++;
                Q[coada]=*p;
            }
            ++p;
        }
        ++cap;
    }
}

void rezolvare()
{
    int i,j,r,rez=0;
    while (bfs())
    {
        for (i=1; i<=n; ++i)
        {
            if (T[i]==-1 || c[i][n]<=f[i][n])
                continue;
            r=c[i][n]-f[i][n];
            for (j=i; j!=1; j=T[j])
                r=min(r,c[T[j]][j]-f[T[j]][j]);
            if (r==0)
                continue;
            f[i][n]+=r;
            f[n][i]-=r;
            for (j=i; j!=1; j=T[j])
            {
                f[T[j]][j]+=r;
                f[j][T[j]]-=r;
            }
        }
    }

    bf1(1,1);
    bf2(n,2);
    for (i=1; i<=m; ++i)
        if (mark[x[i]]+mark[y[i]]==3)
            rez++;
    fout << rez << "\n";
    for (i=1; i <=m; ++i)
        if (mark[x[i]]+mark[y[i]]==3)
            fout << i << "\n";
}

int main()
{
    citire();
    rezolvare();
}