Cod sursa(job #1559154)

Utilizator Liviu98Dinca Liviu Liviu98 Data 30 decembrie 2015 12:45:42
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.5 kb
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define Nmax 605
#define INFINIT 0x3f3f3f3f
#define Sursa 0
#define Destinatie 604
using namespace std;
vector <int> Graf[Nmax];
int Capacitate[Nmax][Nmax],Flux[Nmax][Nmax];
int Nr[Nmax][Nmax],Cost[Nmax][Nmax],Tata[Nmax],dist[Nmax];
int N,M,E,flow,FlowCost;
bool InCoada[Nmax];

void Read()
{
    int x,y,z;
    scanf("%d%d%d",&N,&M,&E);
    for(int i=1;i<=E;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        y+=N;
        Graf[x].push_back(y);
        Graf[y].push_back(x);
        Capacitate[x][y]=1;
        Cost[x][y]=z;
        Cost[y][x]=-z;
        Nr[x][y]=i;
    }

    for(int i=1;i<=N;i++)
    {
        Graf[Sursa].push_back(i);
        Graf[i].push_back(Sursa);
        Capacitate[Sursa][i]=1;
    }

    for(int i=N+1;i<=N+M;i++)
    {
        Graf[i].push_back(Destinatie);
        Graf[Destinatie].push_back(i);
        Capacitate[i][Destinatie]=1;
    }
}

bool BellManFord()
{
    int Fluxminim;
    queue<int> Q;
    memset(dist,INFINIT,sizeof(dist));
    dist[Sursa]=0;
    for(Q.push(Sursa);!Q.empty();Q.pop())
    {
        int nod=Q.front();
        InCoada[nod]=false;
        for(vector<int>::iterator it=Graf[nod].begin();it!=Graf[nod].end();it++)
        {
            if(Capacitate[nod][*it]==Flux[nod][*it]) continue;
            if(dist[nod]+Cost[nod][*it]<dist[*it])
            {
                dist[*it]=dist[nod]+Cost[nod][*it];
                Tata[*it]=nod;
                if(InCoada[*it]==false)
                {
                    InCoada[*it]=true;
                    Q.push(*it);
                }
            }
        }
    }
    if(dist[Destinatie]==INFINIT)
    return false;
    Fluxminim=INFINIT;

    for(int i=Destinatie;i!=Sursa;i=Tata[i])
    {
        Fluxminim=min(Fluxminim,Capacitate[Tata[i]][i]-Flux[Tata[i]][i]);
    }
    for(int i=Destinatie;i!=Sursa;i=Tata[i])
    {
        Flux[Tata[i]][i]+=Fluxminim;
        Flux[i][Tata[i]]-=Fluxminim;
    }
    flow+=Fluxminim;
    FlowCost+=Fluxminim*dist[Destinatie];
    return true;
}

void Solve()
{
    while(BellManFord());

    printf("%d %d\n",flow,FlowCost);
    for(int i=1;i<=N;i++)
    {
        for(int j=N+1;j<=N+M;j++)
        {
            if(Capacitate[i][j]&&Flux[i][j]) printf("%d ", Nr[i][j]);
        }
    }
}

int main()
{
    freopen("cmcm.in", "r", stdin);
    freopen("cmcm.out", "w", stdout);
    Read();
    Solve();
}