Cod sursa(job #2695597)

Utilizator BourucLiviuBouruc Petru Liviu BourucLiviu Data 13 ianuarie 2021 20:52:45
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

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

const int NMAX = 603, INF = 1e9;

int N, M, E, d;
vector <int> G[NMAX];
int cost[NMAX][NMAX], C[NMAX][NMAX], muchie[NMAX][NMAX], dist[NMAX], pred[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 nod = Q.front();
        inQ[nod] = false;
        Q.pop();

        for (auto i: G[nod])
            if(C[nod][i] && dist[i] > dist[nod] + cost[nod][i])
            {
                dist[i] = dist[nod] + cost[nod][i];
                pred[i] = nod;
                if (!inQ[i])
                {
                    Q.push(i);
                    inQ[i] = true;
                }
            }
    }
    return (dist[d] != INF);
}

int main()
{
    fin >> N >> M >> E;
    d = N + M + 1;
    for (int i = 1, P, Q, c; i <= E; ++i)
    {
        fin >> P >> Q >> c;
        Q += N;
        muchie[P][Q] = i;
        G[P].push_back(Q);
        G[Q].push_back(P);
        cost[P][Q] = c;
        cost[Q][P] = -c;
        C[P][Q] = 1;
    }

    for (int i = 1; i <= N; ++i)
    {
        G[0].push_back(i);
        G[i].push_back(0);
        C[0][i] = 1;
    }
    for (int i = N + 1; i <= M + N; ++i)
    {
        G[i].push_back(d);
        G[d].push_back(i);
        C[i][d] = 1;
    }

    int Nr = 0, K = 0, minF, nod;
    while(BellmanFord())
    {
        minF = INF;
        nod = d;
        while (nod != 0)
        {
            minF = min(minF, C[pred[nod]][nod]);
            nod = pred[nod];
        }

        Nr += minF;
        K += minF * dist[d];
        nod = d;
        while (nod != 0)
        {
            C[pred[nod]][nod] -= minF;
            C[nod][pred[nod]] += minF;
            nod = pred[nod];
        }
    }

    fout << Nr << ' ' << K << '\n';
    for (int i = 1; i <= N; ++i)
        for (int j = N + 1; j <= M+N; ++j)
            if (!C[i][j] && muchie[i][j]) fout << muchie[i][j] << " ";
    fin.close(); fout.close();
    return 0;
}