Cod sursa(job #3191636)

Utilizator omaclearuMacelaru Octavian Andrei omaclearu Data 10 ianuarie 2024 11:43:00
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <fstream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;

class MinCostMaxFlow {
private:
    int n, m, e, S, D;
    vector<pair<int, int>> edges;
    vector<vector<int>> G;
    vector<vector<int>> cap;
    vector<vector<int>> cost;
    vector<int> dmin, father;
    vector<bool> inQueue;
    queue<int> q;
    int cnt, totalCost;

public:
    MinCostMaxFlow(ifstream &fin, ofstream &fout) {
        readData(fin);
        while (bellmanFord());
        fout << totalCost;
    }

private:
    void readData(ifstream &f) {
        f >> n;
        m = n;

        S = 0;
        D = n + m + 1;

        // Initialize vectors
        G.assign(D + 1, vector<int>());
        cap.assign(D + 1, vector<int>(D + 1, 0));
        cost.assign(D + 1, vector<int>(D + 1, 0));
        dmin.assign(D + 1, INT_MAX);
        father.assign(D + 1, 0);
        inQueue.assign(D + 1, false);

        for (int i = 1; i <= n; ++i) {
            G[S].push_back(i);
            G[i].push_back(S);
            cap[S][i] = 1;
        }

        for (int i = n + 1; i <= n + m; ++i) {
            G[i].push_back(D);
            G[D].push_back(i);
            cap[i][D] = 1;
        }

        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                int u, v, c;
                f >> c;

                u = i;
                v = j + n;

                G[u].push_back(v);
                G[v].push_back(u);
                cap[u][v] = 1;

                cost[u][v] = c;
                cost[v][u] = -c;

                edges.push_back(make_pair(u, v));
            }
        }
    }

    bool bellmanFord() {
        for (int i = S; i <= D; ++i) {
            inQueue[i] = false;
            dmin[i] = INT_MAX;
        }

        int node = S;
        q.push(node);
        dmin[node] = 0;

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

            for (int nxt: G[node])
                if (dmin[node] + cost[node][nxt] < dmin[nxt] && cap[node][nxt] > 0) {
                    father[nxt] = node;
                    dmin[nxt] = dmin[node] + cost[node][nxt];
                    if (!inQueue[nxt]) {
                        inQueue[nxt] = true;
                        q.push(nxt);
                    }
                }
        }

        if (dmin[D] == INT_MAX) {
            return false;
        } else {
            cnt++;
            node = D;
            while (node != S) {
                cap[father[node]][node]--;
                cap[node][father[node]]++;
                totalCost += cost[father[node]][node];
                node = father[node];
            }

            return true;
        }
    }
};

int main() {
    ifstream fin("cc.in");
    ofstream fout("cc.out");

    MinCostMaxFlow minCostMaxFlow(fin, fout);

    fin.close();
    fout.close();

    return 0;
}