Cod sursa(job #2695633)

Utilizator anacomoAna-Maria Comorasu anacomo Data 14 ianuarie 2021 00:10:07
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <bits/stdc++.h>
using namespace std;
ifstream in("cmcm.in");
ofstream out("cmcm.out");
const int MAXN = 603, INF = 2e9;
int N, M, E, d;
int Nr, min_cost;
vector<int> adj[MAXN];
int cost[MAXN][MAXN], C[MAXN][MAXN], edge[MAXN][MAXN], dist[MAXN], par[MAXN];
bool inQ[MAXN];
queue<int> qu;

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

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

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

        for (auto nbh : adj[current])
            if (C[current][nbh] && dist[nbh] > dist[current] + cost[current][nbh])
            {
                dist[nbh] = dist[current] + cost[current][nbh];
                par[nbh] = current;
                if (!inQ[nbh])
                {
                    qu.push(nbh);
                    inQ[nbh] = true;
                }
            }
    }
    return (dist[d] != INF);
}
void compute()
{
    int minF, current;
    while (BellmanFord())
    {
        minF = INF;
        current = d;
        while (current != 0)
        {
            minF = min(minF, C[par[current]][current]);
            current = par[current];
        }

        Nr += minF;
        min_cost += minF * dist[d];
        current = d;
        while (current != 0)
        {
            C[par[current]][current] -= minF;
            C[current][par[current]] += minF;
            current = par[current];
        }
    }
}

int main()
{
    in >> N >> M >> E;
    d = N + M + 1;
    int P, qu, cst;
    for (int i = 1; i <= E; ++i)
    {
        in >> P >> qu >> cst;
        qu += N;
        edge[P][qu] = i;
        adj[P].push_back(qu);
        adj[qu].push_back(P);
        cost[P][qu] = cst;
        cost[qu][P] = -cst;
        C[P][qu] = 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();
    out << Nr << ' ' << min_cost << '\n';
    for (int i = 1; i <= N; ++i)
        for (int j = N + 1; j <= M + N; ++j)
            if (!C[i][j] && edge[i][j])
                out << edge[i][j] << " ";
    return 0;
}