Cod sursa(job #1941583)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 27 martie 2017 14:28:06
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#include <bits/stdc++.h>
using namespace std;

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

const int NMAX = 605,
           INF = 0x3f3f3f3f;

vector<pair<int, int>> skit;
int n, m, e, src, snk, mat, pen;

vector<int> g[NMAX];
int flw[NMAX][NMAX],
    cst[NMAX][NMAX],
    cap[NMAX][NMAX],
    far[NMAX];

bool bellman() {
    deque<int> dq;
    vector<int> dist;
    bitset<NMAX> iq(0);
    int u, agm;

    dq.push_back(src);
    iq[src] = 1;

    dist.resize(n + m + 2);
    fill(begin(dist), end(dist), INF);
    dist[src] = 0;

    memset(far, 0xFF, sizeof far);

    while (!dq.empty()) {
        u = dq.front(); dq.pop_front();
        iq[u] = false;

        if (u == snk)
            continue;

        for (auto v: g[u]) if (cap[u][v] - flw[u][v] > 0 && dist[u] + cst[u][v] < dist[v]) {
            dist[v] = dist[u] + cst[u][v];
            far[v] = u;
            if (!iq[v])
                iq[v] = true,
                dq.push_back(v); } }

    if (dist[snk] < INF) {
        u = snk;
        while (u != src) {
            pen+= cst[far[u]][u];
            ++flw[far[u]][u];
            --flw[u][far[u]];
            u = far[u]; }

        ++mat;
        return true; }

    return false; }

int main() {
    int a, b, c;

    fi >> n >> m >> e;

    skit.resize(e);
    snk = n + m + 1;
    src = 0;

    for (int i = 1; i <= n; ++i) {
        g[src].push_back(i); cap[src][i] = 1;
        g[i].push_back(src); }
    for (int i = n + 1; i <= n + m; ++i) {
        g[snk].push_back(i);
        g[i].push_back(snk); cap[i][snk] = 1; }

    for (int i = 0; i < e; ++i) {
        fi >> a >> b >> c; b+= n;
        g[a].push_back(b); cap[a][b] = 1;
        g[b].push_back(a);
        cst[a][b] = c;
        cst[b][a] =-c;
        skit[i] = {a, b}; }

    while (bellman());

    fo << mat << ' ' << pen << '\n';
    for (int i = 0; i < e; ++i)
        if (flw[skit[i].first][skit[i].second])
            fo << i + 1 << ' ';
    fo << '\n';

    return 0; }