Cod sursa(job #372361)

Utilizator DraStiKDragos Oprica DraStiK Data 9 decembrie 2009 18:35:21
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.2 kb
#include <algorithm>
#include <vector>
using namespace std;

#define pb push_back
#define mp make_pair
#define INF 1<<31-1
#define sc second
#define fs first
#define DIM 605

int dst[DIM],t[DIM],q[DIM*DIM],viz[DIM];
vector <pair <int,int> > lst[DIM];
int c[DIM][DIM],f[DIM][DIM];
int n,m,e,s,d,cuplaj,cost;

void read ()
{
    freopen ("cmcm.in","r",stdin);
    int i,x,y,z;

    scanf ("%d%d%d",&n,&m,&e);
    s=0; d=n+m+1;
    for (i=1; i<=e; ++i)
    {
        scanf ("%d%d%d",&x,&y,&z);
        c[s][x]=c[x][n+y]=c[n+y][d]=1;
        lst[s].pb (mp (x,0));
        lst[x].pb (mp (s,0));
        lst[x].pb (mp (n+y,z));
        lst[n+y].pb (mp (x,-z));
        lst[n+y].pb (mp (d,0));
        lst[d].pb (mp (n+y,0));
    }
}

int bellman_ford ()
{
    vector <pair <int,int> > :: iterator it;
    int i,st,dr,nod;

    for (i=s; i<=d; ++i)
        dst[i]=INF;
    for (dst[q[st=dr=1]=s]=0; st<=dr; viz[q[st++]]=0)
    {
        nod=q[st];
        for (it=lst[nod].begin (); it!=lst[nod].end (); ++it)
            if (dst[nod]+it->sc<dst[it->fs] && c[nod][it->fs]-f[nod][it->fs]>0)
            {
                dst[it->fs]=dst[nod]+it->sc;
                t[it->fs]=nod;
                if (!viz[it->fs])
                {
                    q[++dr]=it->fs;
                    viz[it->fs]=1;
                }
            }
    }
    if (dst[d]!=INF)
        return 1;
    return 0;
}

void flow ()
{
    int i,nrmin;

    for (nrmin=INF; bellman_ford (); nrmin=INF)
    {
        for (i=d; i!=s; i=t[i])
            nrmin=min (nrmin,c[t[i]][i]-f[t[i]][i]);
        for (i=d; i!=s; i=t[i])
        {
            f[t[i]][i]+=nrmin;
            f[i][t[i]]-=nrmin;
        }
        if (nrmin)
        {
            ++cuplaj;
            cost+=dst[d];
        }
    }
}

void solve ()
{
    freopen ("cmcm.in","r",stdin);
    freopen ("cmcm.out","w",stdout);
    int i,x,y,z;

    printf ("%d %d\n",cuplaj,cost);
    scanf ("%d%d%d",&n,&m,&e);
    for (i=1; i<=e; ++i)
    {
        scanf ("%d%d%d",&x,&y,&z);
        if (f[x][n+y])
            printf ("%d ",i);
    }
}

int main ()
{
    read ();
    flow ();
    solve ();

    return 0;
}