Cod sursa(job #2715402)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 3 martie 2021 17:20:48
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream cin("cmcm.in");
ofstream cout("cmcm.out");

const int INF = 1e9;

const int NMAX = 300;
const int EMAX = 50000;

int N, M, E, S, D;
vector <int> g[2 * NMAX + 5];
pair <int, int> edges[EMAX + 5];

int capacity[2 * NMAX + 5][2 * NMAX + 5], cost[2 * NMAX + 5][2 * NMAX + 5];
int flow[2 * NMAX + 5][2 * NMAX + 5];

bool inQ[2 * NMAX + 5];
int flowTo[2 * NMAX + 5], costTo[2 * NMAX + 5], parent[2 * NMAX + 5];

bool Bellman() {
    for(int i = S; i <= D; i++) {
        flowTo[i] = INF;
        costTo[i] = INF;
        inQ[i] = false;
    }

    queue <int> q;
    q.push(S);
    costTo[S] = 0;
    inQ[S] = true;

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

        for(auto it : g[node]) {
            if(flow[node][it] < capacity[node][it] && costTo[it] > costTo[node] + cost[node][it]) {
                costTo[it] = costTo[node] + cost[node][it];
                flowTo[it] = min(flowTo[node], capacity[node][it] - flow[node][it]);
                parent[it] = node;
                if(!inQ[it]) {
                    inQ[it] = true;
                    q.push(it);
                }
            }
        }
    }

    return (costTo[D] != INF);
}

int main() {
    cin >> N >> M >> E;

    S = 0, D = N + M + 1;

    for(int i = 1; i <= E; i++) {
        int P, Q, C;
        cin >> P >> Q >> C;

        g[P].push_back(N + Q);
        g[N + Q].push_back(P);
        edges[i] = {P, N + Q};

        capacity[P][N + Q] = 1;

        cost[P][N + Q] = C;
        cost[N + Q][P] = -C;
    }

    for(int i = 1; i <= N; i++) {
        g[S].push_back(i);
        g[i].push_back(S);

        capacity[S][i] = 1;
    }

    for(int i = 1; i <= M; i++) {
        g[N + i].push_back(D);
        g[D].push_back(N + i);

        capacity[N + i][D] = 1;
    }

    int maxFlow = 0, minCost = 0;
    while(Bellman()) {

        maxFlow += flowTo[D];
        minCost += costTo[D] * flowTo[D];

        for(int node = D; node != S; node = parent[node]) {
            flow[parent[node]][node] += flowTo[D];
            flow[node][parent[node]] -= flowTo[D];
        }
    }

    cout << maxFlow << ' ' << minCost << '\n';

    for(int i = 1; i <= E; i++) {
        if(flow[edges[i].first][edges[i].second] == 1) {
            cout << i << ' ';
        }
    }

    return 0;
}