Cod sursa(job #1465232)

Utilizator CollermanAndrei Amariei Collerman Data 26 iulie 2015 19:58:24
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
const int NMAX = 610;
const int INF = 1<<30;

int n, m, e, S, D, cost_min, nr;
int C[NMAX][NMAX], Cost[NMAX][NMAX], F[NMAX][NMAX], Tata[NMAX], Drum[NMAX], Muchie[NMAX][NMAX]; // F = graf rezidual
vector<int> Graf[NMAX];
bitset<NMAX> inQueue;

void citire()
{
    fin >> n >> m >> e;
    for(int i=1, x, y, z; i<=e; i++) {
        fin >> x >> y >> z;

        y += n;
        Graf[x].push_back(y);
        Graf[y].push_back(x);
        Cost[x][y] = z;
        Cost[y][x] = -z;
        C[x][y] = 1;
        Muchie[x][y] = i;
    }
}

bool BellmanFord()
{
    inQueue.reset();
    for(int i=S; i<=D; i++) {
         Drum[i] = INF;
         Tata[i] = 0;
         inQueue[i] = 0;
    }

    Drum[S] = 0;
    queue<int> Q;
    Q.push(S);
    inQueue[S] = true;

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

        if(nod == D) continue;

        for(auto x : Graf[nod]) {
            if(C[nod][x] > F[nod][x] && Drum[x] > Drum[nod] + Cost[nod][x]) {
                Drum[x] = Drum[nod] + Cost[nod][x];
                Tata[x] = nod;

                if(!inQueue[x]) {
                    inQueue[x] = true;
                    Q.push(x);
                }
            }
        }
    }

    return Drum[D] != INF;
}

int main()
{
    citire();

    S = 0;
    D = m + n + 1;

    for(int i=1; i<=n; i++) {
        Graf[S].push_back(i);
        C[S][i] = 1;
    }

    for(int i=n+1; i<=m+n; i++) {
        Graf[i].push_back(D);
        C[i][D] = 1;
    }

    while(BellmanFord()) {
        int flux = INF;

        for(int v = D; v != Tata[v]; v = Tata[v])
            flux = min(flux, C[Tata[v]][v] - F[Tata[v]][v]);

        if(!flux) continue;

        for(int v = D; v != Tata[v]; v = Tata[v]) {
            F[Tata[v]][v] += flux;
            F[v][Tata[v]] -= flux;
        }

        nr += flux;
        cost_min += (flux * Drum[D]);
    }

    fout << nr << ' ' << cost_min << '\n';
    for(int i=1; i<=n; i++)
        for(int j=n+1; j<=n+m; j++)
            if(F[i][j]) fout << Muchie[i][j] << ' ';

    return 0;
}