Pagini recente » Cod sursa (job #3127811) | Cod sursa (job #1676262) | Cod sursa (job #482292) | Cod sursa (job #2652684) | Cod sursa (job #3189870)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
class Graf {
int numarNoduri;
std::vector<std::vector<int>> capacitati;
std::vector<std::vector<int>> costuri;
std::vector<std::vector<int>> flux;
public:
explicit Graf(int numarNoduri) : numarNoduri(numarNoduri) {
capacitati.resize(numarNoduri);
costuri.resize(numarNoduri);
flux.resize(numarNoduri);
for (int i = 0; i < numarNoduri; i++) {
capacitati[i].resize(numarNoduri, 0);
costuri[i].resize(numarNoduri, 0);
flux[i].resize(numarNoduri, 0);
}
}
void adaugaCapacitate(int x, int y, int capacitate, int cost) {
capacitati[x][y] = capacitate;
capacitati[y][x] = 0;
costuri[x][y] = cost;
costuri[y][x] = -cost;
}
bool dijkstra(int sursa, int destinatie, std::vector<int>& tati) {
std::vector<int> distante(numarNoduri, INT_MAX);
distante[sursa] = 0;
std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> pq;
pq.push({0, sursa});
while (!pq.empty()) {
int nod = pq.top().second;
int distantaNod = pq.top().first;
pq.pop();
if (distantaNod > distante[nod]) {
continue;
}
for (int vecin = 0; vecin < numarNoduri; vecin++) {
if (capacitati[nod][vecin] - flux[nod][vecin] > 0 &&
distante[nod] != INT_MAX &&
distante[nod] + costuri[nod][vecin] < distante[vecin]) {
distante[vecin] = distante[nod] + costuri[nod][vecin];
tati[vecin] = nod;
pq.push({distante[vecin], vecin});
}
}
}
return distante[destinatie] != INT_MAX;
}
int fluxMaxim(int sursa, int destinatie) {
int fluxMaxim = 0;
std::vector<int> tati(numarNoduri, -1);
while (dijkstra(sursa, destinatie, tati)) {
int fluxMinim = INT_MAX;
int nod = destinatie;
while (nod != sursa) {
fluxMinim = std::min(fluxMinim, capacitati[tati[nod]][nod] - flux[tati[nod]][nod]);
nod = tati[nod];
}
fluxMaxim += fluxMinim;
nod = destinatie;
while (nod != sursa) {
flux[tati[nod]][nod] += fluxMinim;
flux[nod][tati[nod]] -= fluxMinim;
nod = tati[nod];
}
}
return fluxMaxim;
}
int getCostMinim() const {
int costMinim = 0;
for (int i = 0; i < numarNoduri; i++) {
for (int j = 0; j < numarNoduri; j++) {
costMinim += flux[i][j] * costuri[i][j];
}
}
return costMinim;
}
};
int main() {
std::ifstream fin("cc.in");
std::ofstream fout("cc.out");
int N;
fin >> N;
Graf g(2 * N + 2);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
int distance;
fin >> distance;
g.adaugaCapacitate(i, j + N, 1, distance);
}
}
fin.close();
int sursa = 2 * N;
int destinatie = 2 * N + 1;
for (int i = 0; i < N; ++i) {
g.adaugaCapacitate(sursa, i, 1, 0);
}
for (int j = 0; j < N; ++j) {
g.adaugaCapacitate(j + N, destinatie, 1, 0);
}
int maxFlow = g.fluxMaxim(sursa, destinatie);
int minDistanceSum = g.getCostMinim();
minDistanceSum /= 2;
fout << minDistanceSum << '\n';
fout.close();
return 0;
}