Cod sursa(job #2695973)

Utilizator robertnanu_fmiNanu Robert-Ionut robertnanu_fmi Data 14 ianuarie 2021 23:52:42
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <bits/stdc++.h>
using namespace std;

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

const int nMax = 605, INF = 2e9;

int n, m, e, d;
int nr, cost_minim;
vector<int> adj[nMax];
int cost[nMax][nMax], c[nMax][nMax], edges[nMax][nMax], dist[nMax], par[nMax];
bool inQ[nMax];
queue<int> q;

bool BellmanFord()
{
    for (int i = 1; i < nMax; ++i)
        dist[i] = INF;

    dist[0] = 0;
    q.push(0);
    inQ[0] = true;

    while (!q.empty())
    {
        int node = q.front();
        inQ[node] = false;
        q.pop();

        for (auto nbh : adj[node])
            if (c[node][nbh] && dist[nbh] > dist[node] + cost[node][nbh])
            {
                dist[nbh] = dist[node] + cost[node][nbh];
                par[nbh] = node;

                if (!inQ[nbh])
                {
                    q.push(nbh);
                    inQ[nbh] = true;
                }
            }
    }

    return (dist[d] != INF);
}
void compute()
{
    int minF, node;

    while (BellmanFord())
    {
        minF = INF;
        node = d;

        while (node != 0)
        {
            minF = min(minF, c[par[node]][node]);
            node = par[node];
        }

        nr += minF;
        cost_minim += minF * dist[d];
        node = d;

        while (node != 0)
        {
            c[par[node]][node] -= minF;
            c[node][par[node]] += minF;
            node = par[node];
        }
    }
}

int main()
{
    f >> n >> m >> e;
    d = n + m + 1;
    int P, Q, cst;
    for (int i = 1; i <= e; ++i)
    {
        f >> P >> Q >> cst;
        Q += n;
        edges[P][Q] = i;
        adj[P].push_back(Q);
        adj[Q].push_back(P);
        cost[P][Q] = cst;
        cost[Q][P] = -cst;
        c[P][Q] = 1;
    }

    for (int i = 1; i <= n; ++i)
    {
        adj[0].push_back(i);
        adj[i].push_back(0);
        c[0][i] = 1;
    }
    for (int i = n + 1; i <= m + n; ++i)
    {
        adj[i].push_back(d);
        adj[d].push_back(i);
        c[i][d] = 1;
    }

    compute();
    g << nr << ' ' << cost_minim << '\n';
    for (int i = 1; i <= n; ++i)
        for (int j = n + 1; j <= m + n; ++j)
            if (!c[i][j] && edges[i][j])
                g << edges[i][j] << " ";
    return 0;
}