Cod sursa(job #1867188)

Utilizator FlorinHajaFlorin Gabriel Haja FlorinHaja Data 3 februarie 2017 20:31:39
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.5 kb
#include <fstream>
#include <iostream>
#include <vector>
#define siz 705

using namespace std;

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

const int f_mare = 2e9;
vector <int> ls[siz], lc[siz];
int cap[siz][siz], n,m,nm,x,y,c, fl[siz][siz],dist[siz],i,j,G[siz];
int coada[60000], st, dr, tt[siz], fin, fmin, edge[siz][siz],nr;
long long sol;
bool viz[siz];

int bf() {
    for (i = 1; i <= fin; i++) {
        dist[i] = f_mare;
        tt[i]=-1;
        viz[i]=0;
    }
    coada[(st=dr=0)] = 1;
    dist[1]=0;
    viz[1] = 1;
    while (st <= dr) {
        x = coada[st++];
        for (i = 0; i < G[x]; i++) {
            y = ls[x][i];
            c = lc[x][i];
            //cout << x << ' ' << y << " NEXT ";
            if (cap[x][y] - fl[x][y] > 0 && dist[x]+c < dist[y]) {
                dist[y] = dist[x]+c;
                tt[y] = x;
                if (viz[y]) continue;
                viz[y]=1, coada[++dr] = y;
            }
        }
        viz[x] = 0;
    }
    if (dist[fin] != f_mare) {
        fmin = f_mare;
        y = fin;
        while (y != 1) {
            fmin=min(fmin, cap[tt[y]][y]-fl[tt[y]][y]);
            y = tt[y];
        }
        for (y = fin;y!=1;y=tt[y])
            fl[tt[y]][y] += fmin, fl[y][tt[y]] -= fmin;
        return fmin*dist[fin];
        //out << fmin<<"\n";
    }
    return 0;
}


void calc() {
    for (i = 2; i <= n+1; i++) {
        ls[1].push_back(i);
        lc[1].push_back(0);
        ls[i].push_back(1);
        lc[i].push_back(0);
        cap[1][i] = 1;

    }
    for (i = n+2; i < fin; i++) {
        ls[fin].push_back(i);
        ls[i].push_back(fin);
        lc[i].push_back(0);
        lc[fin].push_back(0);
        cap[i][fin] = 1;
    }
    for (i = 1; i <= n+m+2;i++)
        G[i] = ls[i].size();
    int k;
    while ((k=bf()))
        sol += k;
    for (i = 2; i <=n+1;i++)
        for (j = n+2; j<=fin;j++)
            nr += (cap[i][j]&&fl[i][j]);
}

int main() {
    in >> n >> m >> nm;
    fin = n+m+2;
    for (i = 1; i <= nm; i++) {
        in >> x >> y >> c;
        x++, y += n+1;
        ls[x].push_back(y);
        lc[x].push_back(c);
        ls[y].push_back(x);
        lc[y].push_back(-c);
        cap[x][y] = 1;
        edge[x][y] = i;
    }
    calc();
    out<< nr<< ' ' << sol <<'\n';
    for (i = 2; i <=n+1;i++)
        for (j = n+2; j<=fin;j++)
            if (cap[i][j]&&fl[i][j]) {
                out<<edge[i][j]<<' ';
            }
    return 0;
}