Cod sursa(job #3190082)

Utilizator LeVladzCiuperceanu Vlad LeVladz Data 6 ianuarie 2024 22:35:55
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <bits/stdc++.h>

using namespace std;

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

class Graf {
    int n;
    vector<vector<int>> L;
    vector<vector<int>> resid;
    vector<vector<int>> cost;
    vector<int> tata;
    //bitset<1005> f;
    vector<int> dp;
public:
    Graf(int n, vector<vector<int>>& L, vector<vector<int>>& resid, vector<vector<int>>& cost) : n(n), L(L), resid(resid), cost(cost) {
        tata.resize(n+5);
        //f.reset();
        dp.resize(n+5);
    }

    bool dijkstra(int s, int d) {
        for (int i=0; i<=n+1; i++)
            dp[i] = INT_MAX;
        dp[s] = 0; tata[s] = -1;
        set<pair<int, int>> c;
        c.insert({0, s});
        while (!c.empty()) {
            int nod = c.begin()->second;
            c.erase(c.begin());
            for (int i=0; i<L[nod].size(); i++) {
                int vecin = L[nod][i];
                if (resid[nod][vecin] > 0 && dp[vecin] > dp[nod] + cost[nod][vecin]) {
                    c.erase({dp[vecin], vecin});
                    dp[vecin] = dp[nod] + cost[nod][vecin];
                    c.insert({dp[vecin], vecin});
                    tata[vecin] = nod;
                }
            }
        }
        return dp[d] != INT_MAX;
    }

    int min_cost_max_flow(int s, int d) {
        int min_cost = 0;
        while (dijkstra(s, d)) {
            int path_flow = INT_MAX;
            int nod = d;
            while (nod != s) {
                path_flow = min(path_flow, resid[tata[nod]][nod]);
                nod = tata[nod];
            }
            nod = d;
            while (nod != s) {
                resid[tata[nod]][nod] -= path_flow;
                resid[nod][tata[nod]] += path_flow;
                min_cost += path_flow * cost[tata[nod]][nod];
                nod = tata[nod];
            }
        }
        return min_cost;
    }

};

int main() {
    int n, x;
    fin >> n;
    vector<vector<int>> L(2*n+5), resid(2*n+5, vector<int>(2*n+5)), cost(2*n+5, vector<int>(2*n+5));
    for (int i=1; i<=n; i++)
        for (int j=1; j<=n; j++) {
            fin >> x;
            resid[i][n+j] = 1;
            cost[i][n+j] = x; cost[n+j][i] = -x;
            L[i].push_back(n+j); L[n+j].push_back(i);
        }
    for (int i=1; i<=n; i++) {
        resid[0][i] = 1;
        L[0].push_back(i); L[i].push_back(0);
        resid[n+i][2*n+1] = 1;
        L[n+i].push_back(2*n+1); L[2*n+1].push_back(n+i);
    }

    Graf g(2*n+5, L, resid, cost);

    fout << g.min_cost_max_flow(0, 2*n+1) << "\n";

    return 0;
}