Pagini recente » Cod sursa (job #892611) | Cod sursa (job #699695) | Cod sursa (job #246402) | Cod sursa (job #980310) | Cod sursa (job #3191965)
#include <fstream>
#include <vector>
#include <deque>
#include <queue>
using namespace std;
ifstream fin("cc.in");
ofstream fout("cc.out");
const int N = 205;
const int INF = 1e9;
int n, cost, nodStart, nodFinal,distanta[N],costuri[N][N];
int flux[N][N], parinte[N];
bool vizitat[N];
vector<int> graf[N];
// Bellman-Ford pentru drumurile de creștere
int bellmanFord(int nodStart, int nodFinal) {
for (int i = nodStart; i <= nodFinal; ++i) {
parinte[i] = 0;
vizitat[i] = false;
distanta[i] = INF;
}
distanta[nodStart] = 0;
vizitat[nodStart] = true;
queue<int> q;
q.push(nodStart);
while (!q.empty()) {
int nod = q.front();
q.pop();
vizitat[nod] = false;
for (auto vecin : graf[nod]) {
if (flux[nod][vecin] > 0 && distanta[vecin] > distanta[nod] + costuri[nod][vecin]) {
distanta[vecin] = distanta[nod] + costuri[nod][vecin];
parinte[vecin] = nod;
if (!vizitat[vecin]) {
vizitat[vecin] = true;
q.push(vecin);
}
}
}
}
return distanta[nodFinal];
}
int main() {
fin >> n;
// construire graf
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
fin >> cost;
costuri[i][j + n] = cost;
costuri[j + n][i] = -cost;
flux[i][j + n] = 1;
graf[i].push_back(j + n);
graf[j + n].push_back(i);
}
}
// nod de start fictiv 0
// nod final fictiv 2n+1
for (int i = 1; i <= n; ++i) {
graf[0].push_back(i);
graf[i].push_back(0);
graf[2 * n + 1].push_back(i + n);
graf[i + n].push_back(2 * n + 1);
flux[0][i] = 1;
flux[i + n][2 * n + 1] = 1;
}
nodStart = 0;
nodFinal = 2 * n + 1;
int rezultat = 0;
while (true) {
int suma = bellmanFord(nodStart, nodFinal);
if (suma == INF)
break;
int fluxMinim = INF;
for (int i = nodFinal; i != nodStart; i = parinte[i])
fluxMinim = min(fluxMinim, flux[parinte[i]][i]);
for (int i = nodFinal; i != nodStart; i = parinte[i]) {
flux[parinte[i]][i] -= fluxMinim;
flux[i][parinte[i]] += fluxMinim;
}
rezultat = rezultat + suma * fluxMinim;
}
fout << rezultat;
return 0;
}