Pagini recente » Cod sursa (job #291106) | Cod sursa (job #2019847) | Cod sursa (job #1285791) | Cod sursa (job #3257614) | Cod sursa (job #3208372)
#include <fstream>
#include <queue>
using namespace std;
ifstream cin ("fmcm.in");
ofstream cout ("fmcm.out");
struct Arc { int nod_vecin , capacitate , cost , urmatorul; } arce[25001];
int numar_noduri , capat[351] , distanta[351];
pair <int , int> urmatorul[351];
bool Dijkstra (const int nod_sursa , const int nod_destinatie)
{
for (int indice = 1 ; indice <= numar_noduri ; indice++)
{ distanta[indice] = 1000000000; urmatorul[indice] = { }; }
priority_queue < pair <int , int> > optiuni;
optiuni.push({distanta[nod_sursa] = 0 , nod_sursa});
while (!optiuni.empty())
{
if (distanta[optiuni.top().second] != -optiuni.top().first)
{ optiuni.pop(); continue; }
const int nod_actual = optiuni.top().second;
optiuni.pop();
for (int indice = capat[nod_actual] ; indice ; indice = arce[indice].urmatorul) {
if (distanta[arce[indice].nod_vecin] > distanta[nod_actual] + arce[indice].cost && arce[indice].capacitate) {
optiuni.push({-(distanta[arce[indice].nod_vecin] = distanta[nod_actual] + arce[indice].cost) , arce[indice].nod_vecin});
urmatorul[arce[indice].nod_vecin] = {nod_actual , indice};
}
}
}
return distanta[nod_destinatie] != 1000000000;
}
void Bellman_Ford (const int nod_sursa)
{
bool in_coada[351] = { };
for (int indice = 1 ; indice <= numar_noduri ; indice++)
{ distanta[indice] = 1000000000; }
queue <int> candidati;
for (candidati.push(nod_sursa) , distanta[nod_sursa] = 0 , in_coada[nod_sursa] = true ; !candidati.empty() ; candidati.pop())
{
const int nod_actual = candidati.front();
for (int indice = capat[nod_actual] ; indice ; indice = arce[indice].urmatorul) {
if ((indice & 1) && distanta[arce[indice].nod_vecin] > distanta[nod_actual] + arce[indice].cost)
{
distanta[arce[indice].nod_vecin] = distanta[nod_actual] + arce[indice].cost;
if (!in_coada[arce[indice].nod_vecin]) {
candidati.push(arce[indice].nod_vecin);
in_coada[arce[indice].nod_vecin] = true;
}
}
}
in_coada[nod_actual] = false;
}
}
int main ()
{
int numar_arce , nod_sursa , nod_destinatie;
cin >> numar_noduri >> numar_arce >> nod_sursa >> nod_destinatie;
for (int indice = 1 , nod_actual ; indice <= numar_arce ; indice++)
{
cin >> nod_actual >> arce[indice].nod_vecin >> arce[indice].capacitate >> arce[indice].cost;
arce[indice].urmatorul = capat[nod_actual];
capat[nod_actual] = indice;
indice++;
numar_arce++;
arce[indice].nod_vecin = nod_actual;
arce[indice].cost = -arce[indice - 1].cost;
arce[indice].urmatorul = capat[arce[indice - 1].nod_vecin];
capat[arce[indice - 1].nod_vecin] = indice;
arce[indice].capacitate = 0;
}
Bellman_Ford(nod_sursa);
for (int nod_actual = 1 ; nod_actual <= numar_noduri ; nod_actual++) {
for (int indice = capat[nod_actual] ; indice ; indice = arce[indice].urmatorul)
{ arce[indice].cost += distanta[nod_actual] - distanta[arce[indice].nod_vecin]; }
}
int flux_total = 0;
long long cost_total = 0;
const int termen = distanta[nod_destinatie];
while (Dijkstra(nod_sursa , nod_destinatie))
{
int flux_actual = INT32_MAX , cost_actual = 0;
for (int nod_actual = nod_destinatie ; nod_actual != nod_sursa ; nod_actual = urmatorul[nod_actual].first)
{ flux_actual = min(flux_actual , arce[urmatorul[nod_actual].second].capacitate); cost_actual += arce[urmatorul[nod_actual].second].cost; }
for (int nod_actual = nod_destinatie ; nod_actual != nod_sursa ; nod_actual = urmatorul[nod_actual].first)
{ arce[urmatorul[nod_actual].second].capacitate -= flux_actual; arce[urmatorul[nod_actual].second & 1 ? urmatorul[nod_actual].second + 1 : urmatorul[nod_actual].second - 1].capacitate += flux_actual; }
cost_total += 1LL * flux_actual * cost_actual;
flux_total += flux_actual;
}
cout << (cost_total += 1LL * flux_total * termen);
cout.close(); cin.close();
return 0;
}