Cod sursa(job #886057)

Utilizator vendettaSalajan Razvan vendetta Data 22 februarie 2013 17:07:22
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.86 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

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

#define nmax 301*2
#define Mmax 50000
#define ll long long
#define inf (1<<30)

int n, m, E, Cost[nmax][nmax], capac[nmax][nmax], Muchie[nmax][nmax], dist[nmax];
int flux[nmax][nmax];
vector<int> gf[nmax];
int q[nmax*Mmax];
bool viz[nmax];
int t[nmax];

void citeste(){
    f >> n >> m >> E;
    int x, y, z;
    for(int i=1; i<=E; ++i){
        f >> x >> y >> z;
        y += n; gf[x].push_back(y);
        gf[y].push_back(x);
        Cost[x][y] = z;
        Cost[y][x] = -z;
        capac[x][y] = 1;
        Muchie[x][y] = i;
    }
}

inline int Bf(int S, int D){
    for(int i=0; i<=n+m+1; ++i) t[i] = 0, viz[i] = 0, dist[i] = inf;
    int st = 1; int dr = 1;
    q[1] = S; viz[S] = 1;// e in coada
    dist[S] = 0;

    for(; st<=dr; ){
        int nod = q[st]; ++st;
        viz[nod] = 0;// l-am scos din coada
        for(int i=0; i<gf[nod].size(); ++i){
            int vc = gf[nod][i];
            if ( flux[nod][vc] < capac[nod][vc] && dist[vc] > dist[nod] + Cost[nod][vc] ){
                dist[vc] = dist[nod] + Cost[nod][vc];
                t[vc] = nod;
                if (viz[vc] == 0){
                    viz[vc] = 1;
                    q[++dr] = vc;
                }
            }
        }
    }
    return dist[D];
}

void rezolva(){
    // am reindexat nodurile din a 2 multime iar apoi mai adaug o sursa si o destinatie si bag un flux maxim de cost minim
    int S = 0;
    for(int i=1; i<=n; ++i){
        gf[S].push_back(i);
        gf[i].push_back(S);
        capac[S][i] = 1;
    }
    int D = n + m + 1;
    for(int i=n+1; i<=n+m; ++i){
        gf[i].push_back(D);
        gf[D].push_back(i);
        capac[i][D] = 1;
    }

    int Flux = 0; int CostMin = 0;
    for(int ok=1; ok==1; ){
        int CostDrum = Bf(S, D); if (CostDrum == inf) break;// daca numai exista drumuri din sursa la destinatie ; ma opresc
        // aleg muchia minima
        int Min = inf;
        for(int i=D; i!=S; i=t[i]){
            // am flux pe muhia t[i] -> i;
            Min = min(Min, capac[ t[i] ][i] - flux[ t[i] ][i]);
        }
        // bag fluxul
        for(int i=D; i!=S; i=t[i]){
            flux[ t[i] ][i] += Min;
            flux[ i ][ t[i] ] -= Min; // il intorc
        }
        Flux += Min; CostMin += CostDrum;
    }

    //cout << Flux << " " << CostMin << "\n";
    g << Flux << " " << CostMin << "\n";
    for(int i=1; i<=n; ++i){
        for(int j=n+1; j<=n+m; ++j){
            if (flux[i][j] > 0){
                //cout << Muchie[i][j] << " ";
                g << Muchie[i][j] << " ";;
            }
        }
    }
}

int main(){
    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;
}