Cod sursa(job #968129)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 1 iulie 2013 20:26:57
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.24 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#include<deque>
#include<bitset>
#define pb push_back

using namespace std;
const int NMAX = 610;
const int INF = 1<<30;

int i,j,N,M,E,X,Y,C,S,D,From,Dist[NMAX],Father[NMAX],MinFlow,MaxFlow,CostMin;
int Edge[NMAX][NMAX],Cap[NMAX][NMAX],Flow[NMAX][NMAX],Cost[NMAX][NMAX];

vector<int> V[NMAX];
vector<int>::iterator it;
deque<int> Q;
bool InQ[NMAX];

void Read()
{
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    scanf("%d%d%d",&N,&M,&E);
    for(i=1;i<=E;i++)
    {
        scanf("%d%d%d",&X,&Y,&C); Y+=N;
        V[X].pb(Y); V[Y].pb(X);
        Edge[X][Y]=i;
        Cap[X][Y]=1; Cap[Y][X]=0;
        Cost[X][Y]=C; Cost[Y][X]=-C;
    }
}

void BuildEdges()
{
    S=0; D=N+M+1; Father[S]=S;
    for(i=1;i<=N;i++)
    {
        V[S].pb(i); V[i].pb(S);
        Cap[S][i]=1; Cap[i][S]=0;
        Cost[S][i]=Cost[i][S]=0;
    }
    for(i=N+1;i<=N+M;i++)
    {
        V[i].pb(D); V[D].pb(i);
        Cap[i][D]=1; Cap[D][i]=0;
        Cost[i][D]=Cost[D][i]=0;
    }
}

int BellmanFord()
{
    for(i=1;i<=N+M+1;i++) Dist[i]=INF;
    Q.pb(S); InQ[S]=1; Dist[S]=0;
    while(!Q.empty())
    {
        From=Q.front(); Q.pop_front(); InQ[From]=0;
        for(it=V[From].begin();it!=V[From].end();it++)
            if(Flow[From][*it]<Cap[From][*it] && Dist[From]+Cost[From][*it]<Dist[*it])
            {
                Dist[*it]=Dist[From]+Cost[From][*it];
                Father[*it]=From;
                if(!InQ[*it]) {InQ[*it]=1; Q.pb(*it);}
            }
    }
    return Dist[D]!=INF;
}

void MaxFlowCostMin()
{
    while(BellmanFord())
    {
        for(MinFlow=INF,X=D;X!=Father[X];X=Father[X])
            MinFlow=min(MinFlow,Cap[Father[X]][X]-Flow[Father[X]][X]);
        for(X=D;X!=Father[X];X=Father[X])
        {
            Flow[Father[X]][X]+=MinFlow;
            Flow[X][Father[X]]-=MinFlow;
        }
        MaxFlow+=MinFlow; CostMin+=Dist[D];
    }
}

void Print()
{
    printf("%d %d\n",MaxFlow,CostMin);
    for(i=1;i<=N;i++)
        for(j=N+1;j<=N+M;j++)
            if(Flow[i][j]) printf("%d ",Edge[i][j]);
}

int main()
{
    Read();
    BuildEdges();
    MaxFlowCostMin();
    Print();
    return 0;
}