Cod sursa(job #902208)

Utilizator costi_.-.Costinnel costi_.-. Data 1 martie 2013 13:15:48
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#include<fstream>
#define nmax 604
#define inf 1<<30
using namespace std;

struct nod_lista{
    int val;
    nod_lista *link;
};

nod_lista *G[nmax],*Last[nmax];
int cap[nmax][nmax],flux[nmax][nmax],Q[4*nmax],T[nmax],dist[nmax],cost[nmax][nmax],
     ed[nmax][nmax],LEFT[nmax],RIGHT[nmax],bL[nmax],bR[nmax];
int L,R,E,S,D,NR,K,nr,KL,KR,N,FLUX;

void adauga(int unde,int ce)
{
    nod_lista *q=new nod_lista;
    q->link=NULL;
    q->val=ce;
    if(!G[unde])
    G[unde]=Last[unde]=q;
    else
    {
        Last[unde]->link=q;
        Last[unde]=q;
    }
}

void citeste()
{
    ifstream f("cmcm.in");
    int i,x,y,c;

    f>>L>>R>>E;
    S=L+R+1;
    D=L+R+2;
    N=D;

    for(i=1;i<=E;i++)
    {
        f>>x>>y>>c;
        adauga(x,y+L);
        adauga(y+L,x);
        cap[x][y+L]=1;
        cost[x][y+L]=c;
        cost[y+L][x]=-c;
        ed[x][y+L]=i;

        if(!bL[x])
        {
            LEFT[++KL]=x;
            bL[x]=1;
        }
        if(!bR[y])
        {
            RIGHT[++KR]=y;
            bR[y]=1;
        }
    }
}

void construieste_graf()
{
    int i;
    for(i=1;i<=L;i++)
    {
        adauga(S,LEFT[i]);
        adauga(LEFT[i],S);
        cap[S][LEFT[i]]=1;
    }

    for(i=1;i<=R;i++)
    {
        adauga(RIGHT[i]+L,D);
        adauga(D,RIGHT[i]+L);
        cap[RIGHT[i]+L][D]=1;
    }
}

//graful e gata

int BellmanFord(int S,int D)
{
    int p,q,nod,vecin;
    nod_lista *it;

    for(int i=1;i<=N;i++)
    dist[i]=inf;

    dist[S]=0;
    p=q=0;
    Q[++q]=S;
    while(p<q)
    {
        nod=Q[++p];
        it=G[nod];
        while(it)
        {
            vecin=it->val;
            if(cap[nod][vecin]-flux[nod][vecin]>0 &&
               dist[vecin]>dist[nod]+cost[nod][vecin])
               {
                   dist[vecin]=dist[nod]+cost[nod][vecin];
                   T[vecin]=nod;
                   Q[++q]=vecin;
               }

            it=it->link;
        }
    }

    if(dist[D]!=inf)
    return 1;
    return 0;
}

void saturare()
{
    int nod,cmin;

    cmin=inf;
    nod=D;

    while(nod!=S)
    {
        if(cap[T[nod]][nod]-flux[T[nod]][nod]<cmin)
        cmin=cap[T[nod]][nod]-flux[T[nod]][nod];
        nod=T[nod];
    }
    nod=D;
    while(nod!=S)
    {
        flux[T[nod]][nod]+=cmin;
        flux[nod][T[nod]]-=cmin;
        nod=T[nod];
    }

    FLUX+=cmin;
    K+=cmin*dist[D];
}

void rezolva()
{
    construieste_graf();
    while(BellmanFord(S,D))
    saturare();
}

void scrie()
{
    int stop;
    ofstream g("cmcm.out");
    g<<FLUX<<' '<<K<<'\n';

    for(int i=1;i<=L;i++)
    {
        stop=0;
        for(int j=1;j<=R && !stop;j++)
         if(flux[LEFT[i]][RIGHT[j]+L]>0)
         {
             g<<ed[LEFT[i]][RIGHT[j]+L]<<' ';
             stop=1;
         }
    }


    g.close();
}

int main()
{
    citeste();
    rezolva();
    scrie();
    return 0;
}