Cod sursa(job #3190678)

Utilizator davidtoma11Toma David davidtoma11 Data 7 ianuarie 2024 20:09:25
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.25 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <map>
#include <climits>

using namespace std;

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

int costs[202][202];

class Graph {
    vector<vector<int>> edges;
    map<pair<int, int>, int> edgeValues; // Mapează perechile de noduri la costurile muchiilor
    int numNodes;

public:
    Graph(int n = 1) : numNodes(n) {
        edges = vector<vector<int>>(n + 1);
    }

    void addEdge(int x, int y, int cost = 0) {
        edges[x].push_back(y);
        edgeValues[{x, y}] = cost;
    }

    void setEdgeValue(int x, int y, int newValue) {
        edgeValues[{x, y}] = newValue;
    }

    int getEdgeValue(int x, int y) {
        return edgeValues[{x, y}];
    }

    void maxFlowBFS(vector<int> &parents, int start, int sink) {
        queue<pair<int, int>> q;
        q.push(make_pair(start, INT_MAX)); // Am modificat aici pentru a folosi make_pair
        vector<int> minCost(numNodes, INT_MAX), inQueue(numNodes, 0);
        parents[start] = start;
        minCost[start] = 0;

        while (!q.empty()) {
            int currentNode = q.front().first, maxFlow = q.front().second;
            inQueue[currentNode] = 0;

            for (auto &neighbor : edges[currentNode]) {
                if (edgeValues[{currentNode, neighbor}] > 0 && minCost[neighbor] > minCost[currentNode] + costs[currentNode][neighbor]) {
                    minCost[neighbor] = minCost[currentNode] + costs[currentNode][neighbor];
                    parents[neighbor] = currentNode;

                    if (!inQueue[neighbor]) {
                        inQueue[neighbor] = 1;
                        q.push(make_pair(neighbor, min(edgeValues[{currentNode, neighbor}], maxFlow)));
                    }
                }
            }
            q.pop();
        }
    }

    void maxFlow(int n) {
        int result = 0;
        vector<int> parents(202, -1);
        parents[201] = 201;

        while (parents[201] != -1) {
            parents.assign(202, -1);
            maxFlowBFS(parents, 0, 201);

            if (parents[201] != -1) {
                int currentNode = 201;

                while (currentNode != 0) {
                    edgeValues[{parents[currentNode], currentNode}] -= 1;
                    edgeValues[{currentNode, parents[currentNode]}] += 1;
                    currentNode = parents[currentNode];
                }
            }
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (edgeValues[{100 + j, i}] > 0) {
                    result += costs[i][100 + j];
                }
            }
        }
        fout << result << '\n';
    }
};

int main() {
    int n;
    fin >> n;
    Graph g(202);

    for (int i = 1; i <= n; i++) {
        g.addEdge(0, i, 1);
        g.addEdge(i, 0, 0);
        g.addEdge(100 + i, 201, 1);
        g.addEdge(201, 100 + i, 0);

        for (int j = 1; j <= n; j++) {
            fin >> costs[i][100 + j];
            costs[100 + j][i] -= costs[i][100 + j];
            g.addEdge(i, 100 + j, 1);
            g.addEdge(100 + j, i, 0);
        }
    }

    g.maxFlow(n);

    return 0;
}