Pagini recente » Cod sursa (job #621958) | Borderou de evaluare (job #157079) | Cod sursa (job #3279319) | Cod sursa (job #545994) | Cod sursa (job #2962167)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
int n, m, sursa , destinatie;
vector<vector<int>> listaAdiacenta;
vector<vector<int>> capacitate;
vector<vector<int>> flux;
vector<vector<int>> cost;
vector<int> costbf;
vector<int> tata;
vector<bool>viz;
vector<int> costreal;
vector<int> costfictiv;
void citire()
{
fin>> n >> m>>sursa>>destinatie;
listaAdiacenta = vector<vector<int>>(n+1, vector<int>());
capacitate = vector<vector<int>>(n+1, vector<int>(n+1, 0));
flux = vector<vector<int>>(n + 1, vector<int>(n + 1, 0));
cost = vector<vector<int>>(n + 1, vector<int>(n + 1, 0));
int x, y, cap, cos;
for (int i = 0; i < m; i++)
{
fin >> x >> y >> cap >> cos;
listaAdiacenta[x].push_back(y);
listaAdiacenta[y].push_back(x);
cost[x][y] = cos;
cost[y][x] = -cos;
capacitate[x][y] = cap;
}
}
// functia determina costul de a ajunge din sursa la fiecare nod folosind algoritmul Bellmanford
void bellmanFord()
{
costbf = vector<int>(n + 1, INT_MAX);
costbf[sursa] = 0;
queue<int> coada;
coada.push(sursa);
while (!coada.empty())
{
int nod = coada.front();
coada.pop();
for (auto urm : listaAdiacenta[nod])
{
if (capacitate[nod][urm] > 0 && costbf[nod] + cost[nod][urm] < costbf[urm])
{
costbf[urm] = costbf[nod] + cost[nod][urm];
coada.push(urm);
}
}
}
}
bool dijkstra()
{
tata = vector<int>(n + 1, -1);
viz = vector<bool>(n + 1, false);
costfictiv = vector<int>(n + 1, INT_MAX);
costreal = vector<int>(n + 1, INT_MAX);
priority_queue<pair<int,int>> coada;
costreal[sursa] = 0;
costfictiv[sursa] = 0;
tata[sursa] = 0;
coada.push({ -costfictiv[sursa],sursa });
while (!coada.empty())
{
int nod = coada.top().second;
coada.pop();
if (viz[nod] == true)
{
continue;
}
viz[nod] = true;
for (auto v : listaAdiacenta[nod])
{
int val = costfictiv[nod] + costbf[nod] - costbf[v] + cost[nod][v];
if (flux[nod][v] < capacitate[nod][v] && val < costfictiv[v])
{
costfictiv[v] = val;
costreal[v] = costreal[nod] + cost[nod][v];
tata[v] = nod;
coada.push({ -costfictiv[v],v });
}
}
}
for (int i = 1; i <= n; i++)
{
costbf[i]=costreal[i];
}
return tata[destinatie] != -1;
}
int fordFulkerson()
{
int rezultat = 0;
// determinam drumul de cost minim de la sursa la destinatie
while (dijkstra())
{
int fluxC = INT16_MAX, costTotal = 0;
int nod = destinatie;
// determinam fluxul lantului descoperit
while (nod != sursa)
{
int pred = tata[nod];
fluxC = min(fluxC, capacitate[pred][nod] - flux[pred][nod]);
costTotal += cost[pred][nod];
nod = pred;
}
nod = destinatie;
// revizuim fluxurile
while (nod != sursa)
{
int pred = tata[nod];
flux[pred][nod] += fluxC;
flux[nod][pred] -= fluxC;
nod = pred;
}
rezultat += costTotal * fluxC;
}
return rezultat;
}
int main()
{
citire();
bellmanFord();
fout<<fordFulkerson();
}