Cod sursa(job #469883)

Utilizator ionutz32Ilie Ionut ionutz32 Data 9 iulie 2010 14:51:48
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.45 kb
#include <stdio.h>
#include <vector>
#define s (l+r+1)
#define d (l+r+2)
#define inf 0x7fffffff

using namespace std;

vector<int> graf[605];
vector<int>::iterator u;
int l,r,e,i,x,y,z,cost[605][605],cap[605][605],f[605][605],flow,mincost,dist[605],heap[605],difmin[605],poz[605],tt[605],first,aux,minim,a[305][305];
bool k;

inline void heap_up(int p)
{
    while (p>1 && dist[heap[p]]<dist[heap[p>>1]])
    {
        aux=heap[p];
        heap[p]=heap[p>>1];
        heap[p>>1]=aux;
        poz[heap[p]]=p;
        poz[heap[p>>1]]=p>>1;
        p>>=1;
    }
}

inline void heap_down(int p)
{
    while ((p*2<=x && dist[heap[p]]>dist[heap[p*2]]) || (p*2+1<=x && dist[heap[p]]>dist[heap[p*2+1]]))
    {
        if (p*2+1<=x)
            if (dist[heap[p*2]]<dist[heap[p*2+1]])
                minim=p*2;
            else
                minim=p*2+1;
        else
            minim=p*2;
        aux=heap[p];
        heap[p]=heap[minim];
        heap[minim]=aux;
        poz[heap[p]]=p;
        poz[heap[minim]]=minim;
        p=minim;
    }
}

int main()
{
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    scanf("%d %d %d",&l,&r,&e);
    for (i=1;i<=e;++i)
    {
        scanf("%d %d %d",&x,&y,&z);
        a[x][y]=i;
        graf[x].push_back(l+y);
        graf[l+y].push_back(x);
        cost[x][l+y]=z;
        cost[l+y][x]=-z;
        cap[x][l+y]=1;
    }
    for (i=1;i<=l;++i)
    {
        graf[s].push_back(i);
        graf[i].push_back(s);
        cap[s][i]=1;
    }
    for (i=1;i<=r;++i)
    {
        graf[i+l].push_back(d);
        graf[d].push_back(i+l);
        cap[i+l][d]=1;
    }
    k=true;
    while (k)
    {
        k=false;
        for (i=1;i<=d;++i)
        {
            dist[i]=inf;
            poz[i]=0;
        }
        heap[x=1]=s;
        poz[s]=1;
        dist[s]=0;
        difmin[s]=inf;
        while (x)
        {
            first=heap[1];
            poz[first]=0;
            if (first==d)
                k=true;
            if (x==1)
                x=0;
            else
            {
                heap[1]=heap[x--];
                poz[heap[1]]=1;
                heap_down(1);
            }
            for (u=graf[first].begin();u!=graf[first].end();++u)
                if (cap[first][*u]>f[first][*u] && dist[first]+cost[first][*u]<dist[*u])
                {
                    dist[*u]=dist[first]+cost[first][*u];
                    if (cap[first][*u]-f[first][*u]<difmin[first])
                        difmin[*u]=cap[first][*u]-f[first][*u];
                    else
                        difmin[*u]=difmin[first];
                    tt[*u]=first;
                    if (poz[*u])
                        heap_up(poz[*u]);
                    else
                    {
                        heap[++x]=*u;
                        poz[*u]=x;
                        heap_up(x);
                    }
                }
        }
        if (k)
        {
            flow+=difmin[d];
            mincost+=dist[d]*difmin[d];
            for (i=d;i!=s;i=tt[i])
            {
                f[tt[i]][i]+=difmin[d];
                f[i][tt[i]]-=difmin[d];
            }
        }
    }
    printf("%d %d\n",flow,mincost);
    for (i=1;i<=l;++i)
        if (f[s][i])
            for (u=graf[i].begin();u!=graf[i].end();++u)
                if (f[i][*u]>0)
                    printf("%d ",a[i][*u-l]);
    return 0;
}