Cod sursa(job #603570)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 17 iulie 2011 15:04:49
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.19 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

#define Infinit 2000000000
#define NMax 305

using namespace std;

vector <int> G[NMax];
int N, Index[NMax][NMax], Cost[NMax][NMax], n;

int Source, Destination, Cap[NMax][NMax], Flow[NMax][NMax];

int Dist[NMax], Father[NMax];
queue <int> Queue;
bool InQueue[NMax];

int CardinalCMCM, CostCMCM;

void Read ()
{
    ifstream fin ("cmcm.in");
    int E, M;
    fin >> n >> M >> E;
    N=n+M+2;
    Source=1;
    Destination=N;
    for (int i=1; i<=E; ++i)
    {
        int X, Y, Z;
        fin >> X >> Y >> Z;
        ++X;
        Y+=(n+1);
        G[X].push_back (Y);
        G[Y].push_back (X);
        Cap[X][Y]=1;
        Cost[X][Y]=Z;
        Cost[Y][X]=-Z;
        Index[X][Y]=i;
        if (Cap[Source][X]==0)
        {
            G[Source].push_back (X);
            G[X].push_back (Source);
            Cap[Source][X]=1;
        }
        if (Cap[Y][Destination]==0)
        {
            G[Y].push_back (Destination);
            G[Destination].push_back (Y);
            Cap[Y][Destination]=1;
        }
    }
    fin.close ();
}

void Write ()
{
    ofstream fout ("cmcm.out");
    fout << CardinalCMCM << " " << CostCMCM << "\n";
    for (int i=2; i<=n+1; ++i)
    {
        for (int j=n+2; j<N; ++j)
        {
            if (Cap[i][j]>0 and Flow[i][j]>0)
            {
                fout << Index[i][j] << " ";
            }
        }
    }
    fout << "\n";
    fout.close ();
}

inline int Min (int a, int b)
{
    if (a<b)
    {
        return a;
    }
    return b;
}

void Initialize (int Start)
{
    for (int i=1; i<=N; ++i)
    {
        Dist[i]=Infinit;
        InQueue[i]=false;
    }
    Dist[Start]=0;
    Queue.push (Start);
    InQueue[Start]=true;
}

int BellmanFord (int Start, int End)
{
    Initialize (Start);
    while (!Queue.empty ())
    {
        int X=Queue.front ();
        Queue.pop ();
        InQueue[X]=false;
        for (unsigned v=0; v<G[X].size (); ++v)
        {
            int V=G[X][v];
            if (Dist[X]+Cost[X][V]<Dist[V] and Cap[X][V]-Flow[X][V]>0)
            {
                Dist[V]=Dist[X]+Cost[X][V];
                Father[V]=X;
                if (!InQueue[V])
                {
                    Queue.push (V);
                    InQueue[V]=true;
                }
            }
        }
    }
    return Dist[End];
}

void CMCM (int S, int D)
{
    while (BellmanFord (S, D)!=Infinit)
    {
        int CurrentFlow=Infinit;
        for (int X=D; X!=S; X=Father[X])
        {
            CurrentFlow=Min (CurrentFlow, Cap[Father[X]][X]-Flow[Father[X]][X]);
        }
        for (int X=D; X!=S; X=Father[X])
        {
            Flow[Father[X]][X]+=CurrentFlow;
            Flow[X][Father[X]]-=CurrentFlow;
        }
        CostCMCM+=(Dist[D]*CurrentFlow);
    }
    for (int i=2; i<=n+1; ++i)
    {
        for (int j=n+2; j<N; ++j)
        {
            if (Cap[i][j]>0 and Flow[i][j]>0)
            {
                ++CardinalCMCM;
            }
        }
    }
}

int main()
{
    Read ();
    CMCM (Source, Destination);
    Write ();
    return 0;
}