Cod sursa(job #1957615)

Utilizator FlorinHajaFlorin Gabriel Haja FlorinHaja Data 7 aprilie 2017 17:37:37
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.31 kb
#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

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

const int nmax = 700, f_mare = 2e9;
int n, m, i, j, r, fin, x, y, c;
int coada[nmax*100], st, dr;
int dist[nmax], tt[nmax], edge[nmax][nmax];
int cap[nmax][nmax], fl[nmax][nmax];
bool incoada[nmax];
vector<int> ls[nmax], lc[nmax];

int bf() {
    int i, l, y;
    for (i = 1; i <= fin; i++)
        dist[i] = f_mare, incoada[i] = 0, tt[i] =-1;
    coada[st=dr=0] = 1;
    dist[1] = 0;
    while (st <= dr) {
        x = coada[st++];
        incoada[x] = 0;
        l = ls[x].size();
        for (i = 0; i < l; i++) {
            y = ls[x][i];
            c = lc[x][i];
            if (dist[x] + c < dist[y] && cap[x][y] - fl[x][y] > 0) {
                dist[y] = dist[x]+c;
                tt[y] = x;
                if (incoada[y]) continue;
                incoada[y] = 1;
                coada[++dr] = y;
            }
        }
    }
    if (dist[fin] == f_mare) return 0;
    int flx= f_mare;
    for (x = fin; x > 1; x = tt[x]) flx = min(flx, cap[tt[x]][x] - fl[tt[x]][x]);
    for (x = fin; x > 1; x = tt[x]) fl[tt[x]][x] += flx, fl[x][tt[x]] -= flx;
    return flx*dist[fin];
}

int main() {
    f >> n >> m >> r;
    fin = n+m+2;
    for (i = 1; i <= r; i++) {
        f >> 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;
    }
    for (i = n+2; i <= fin; i++) {
        ls[i].push_back(fin);
        lc[i].push_back(0);
        ls[fin].push_back(i);
        lc[fin].push_back(0);
        cap[i][fin] = 1;
    }
    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;
    }

    int k = 0, nr = 0;
    long long sol = 0;
    while ((k=bf()))
        sol += k;
    for (i = 2; i <= n+1; i++)
        for (j = n+2; j < fin; j++)
            if (cap[i][j] && fl[i][j])
                nr++;

    g << nr << ' ' << sol << '\n';
    for (i = 2; i <= n+1; i++)
        for (j = n+2; j < fin; j++)
            if (cap[i][j] && fl[i][j])
                g << edge[i][j] <<" ";
    return 0;
}