Cod sursa(job #1925868)

Utilizator Theodor1000Cristea Theodor Stefan Theodor1000 Data 13 martie 2017 19:42:32
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

vector <int> v[610];
queue <int> q;

int n, m, e;
int flux[610][610], cap[610][610], cost[610][610], t[610], ret[610], edge[610][610];
bool inq[610];

inline bool bellman ()
{
    bool OK = false;
    for (int i = 2; i <= e; ++i)
        t[i] = 2000000000;

    ret[1] = -1;
    q.push (1);

    for (; !q.empty ();)
    {
        int nod = q.front ();
        q.pop ();

        inq[nod] = false;

        for (auto &it : v[nod])
            if (flux[nod][it] < cap[nod][it] && t[nod] + cost[nod][it] < t[it])
            {
                t[it] = t[nod] + cost[nod][it];
                ret[it] = nod;

                if (it == e) OK = true;
                if (!inq[it]) inq[it] = true, q.push (it);
            }
    }

    return OK;
}

int main ()
{
    freopen ("cmcm.in", "r", stdin);
    freopen ("cmcm.out", "w", stdout);

    scanf ("%d %d %d", &n, &m, &e);

    for (int i = 1; i <= e; ++i)
    {
        int x, y, cos;
        scanf ("%d %d %d", &x, &y, &cos);

        ++x;
        y += n + 1;

        v[x].push_back (y);
        v[y].push_back (x);
        cap[x][y] = 1;
        cost[x][y] = cos;
        cost[y][x] = -cos;

        edge[x][y] = edge[y][x] = i;
    }

    e = n + m + 2;

    for (int i = 1; i <= n; ++i)
        v[1].push_back (i + 1), cap[1][i + 1] = 1;

    for (int i = 1; i <= m; ++i)
        v[i + n + 1].push_back (e), cap[i + n + 1][e] = 1;

    int flow = 0, tcost = 0;
    for (; bellman ();)
    {
        int nod = e, mi = 2000000000;
        for (; ret[nod] != -1; nod = ret[nod])
            mi = min (mi, cap[ret[nod]][nod] - flux[ret[nod]][nod]);

        flow += mi;
        tcost += mi * t[e];

        nod = e;
        for (; ret[nod] != -1; nod = ret[nod])
            flux[ret[nod]][nod] += mi,
            flux[nod][ret[nod]] -= mi;
    }

    printf ("%d %d\n", flow, tcost);

    for (int i = 2; i < e; ++i)
        for (int j = 2; j < e; ++j)
            if (flux[i][j] == 1) printf ("%d ", edge[i][j]);

    printf ("\n");

    return 0;
}