Cod sursa(job #2694369)

Utilizator lauratenderLaura Tender lauratender Data 8 ianuarie 2021 22:42:42
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.33 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <iostream>
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> Q;

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

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

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

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

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

int main()
{
    in >> N >> M >> E;
    d = N + M + 1;
    int P, Q, cst;
    for (int i = 1; i <= E; ++i)
    {
        in >> P >> Q >> cst;
        Q += N;
        edge[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;
    }

    // creez muchiile catre sursa si destinatie
    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;
    }

    Solve();
    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;
}