Cod sursa(job #1621774)

Utilizator emanuel_rRamneantu Emanuel emanuel_r Data 29 februarie 2016 21:37:38
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.48 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<cmath>
#include<queue>

using namespace std;

ifstream f("cmcm.in");
ofstream g("cmcm.out");

vector <pair <int, int> > G[605];
vector <int> Sol;
queue <int> Q;
long long C[605][605], F[605][605], M[605][605];
long long InQ[605], D[605], TT[605];
long long n, m, e, s, d, maxcost, nr;
int const oo = 1000000000;

void citire()
{
    int i, x, y, c;

    f>>n>>m>>e;
    s = 1;
    d = n + m + 2;

    for(i=1; i<=e; i++){
        f>>x>>y>>c;
        G[x + 1].push_back(make_pair(n + 1 + y, c));
        C[x + 1][n + 1 + y] = 1;
        M[x + 1][n + 1 + y] = i;
        G[n + 1 + y].push_back(make_pair(x + 1, -c));
    }
}

void build()
{
    int i;

    for(i=2; i <= n + 1; i++){
        G[1].push_back(make_pair(i, 0));
        C[1][i] = 1;
        G[i].push_back(make_pair(1, 0));
    }
    for(i = n + 2; i <= n + m + 1; i++){
        G[d].push_back(make_pair(i, 0));
        C[i][d] = 1;
        G[i].push_back(make_pair(d, 0));
    }
}

int Bellman()
{
    int i, nod, cost, vecin;

    for(i=2; i<=d; i++){
        D[i] = oo;
        InQ[i] = 0;
    }

    Q.push(s);
    InQ[s] = 1;
    D[i] = 0;

    while(!Q.empty()){
        nod = Q.front();
        InQ[nod] = 0;
        Q.pop();

        for(i = 0; i<G[nod].size(); i++){
            vecin = G[nod][i].first;
            cost = G[nod][i].second;
            if(D[vecin] > D[nod] + cost && C[nod][vecin] - F[nod][vecin] > 0){
                D[vecin] = D[nod] + cost;
                TT[vecin] = nod;
                if(!InQ[vecin]){
                    Q.push(vecin);
                    InQ[vecin] = 1;
                }
            }
        }
    }

    if(D[d] != oo)
        return 1;
    return 0;
}

void Flux()
{
    long long nod, flow, i, j;

    while(Bellman()){
        nod = d;
        flow = oo;
        while(nod != s){
            flow = min(flow, C[TT[nod]][nod] - F[TT[nod]][nod]);
            nod = TT[nod];
        }

        maxcost += D[d];
        nr++;

        nod = d;
        while(nod != s){
            F[TT[nod]][nod] += flow;
            F[nod][TT[nod]] -= flow;
            nod = TT[nod];
        }
    }

    g<<nr<<" "<<maxcost<<"\n";
    for(i=2; i <= n + 1; i++)
        for(j = n + 2; j < d; j++)
            if(F[i][j] && C[i][j])
                g<<M[i][j]<<" ";
    g<<"\n";
}

int main()
{
    citire();
    build();
    Flux();
    return 0;
}