Pagini recente » Cod sursa (job #1989329) | Cod sursa (job #3244621) | Cod sursa (job #831013) | Cod sursa (job #2627798) | Cod sursa (job #1688872)
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 355;
const int INF = 1 << 30;
ifstream in("fmcm.in");
ofstream out("fmcm.out");
int n,sursa,destinatie;
int cost[MAXN][MAXN];//Atentie! Trebuie cu matrice de adiacenta deoarece trebuie costul dintre x si y in O(1)
int capacitate[MAXN][MAXN];//Atentie! Trebuie cu matrice de adiacenta deoarece trebuie capacitatea dintre x si y in O(1)
int flux, flux_maxim_de_cost_minim;
int dvechi[MAXN],dreal[MAXN];
vector<int> vecini[MAXN];
void citire()
{
int m;
in >> n >> m >> sursa >> destinatie;
for(int i = 1;i <= m;++i)
{
int x,y,c,z;
in >> x >> y >> c >> z;
vecini[x].push_back(y);
capacitate[x][y] = c;
cost[x][y] = z;
//se asociaza graful rezidual, o muchie noua intre y si x de cost -z si capacitate 0
vecini[y].push_back(x);
capacitate[y][x] = 0;
cost[y][x] = -z;
}
}
struct nod_dij
{
int nod,cost;
bool operator < (const nod_dij &b) const
{
return cost > b.cost;//heapul din std e de maxime
}
};
int d[MAXN];
int tata[MAXN];
bool dijkstra()//intoarce adevarat daca am gasit drum de ameliorare
{
for (int i = 1;i <= n;++i)
d[i] = INF;
d[sursa] = 0;
dreal[sursa] = 0;
priority_queue<nod_dij> heap;
heap.push((nod_dij){sursa,0});
while(!heap.empty())
{
int cst = heap.top().cost;
int nod = heap.top().nod;
heap.pop();
if (d[nod] != cst)//inseamna ca a fost imbunatatit
continue;
for (unsigned int i = 0;i < vecini[nod].size();++i)
{
int vecin = vecini[nod][i];
if (capacitate[nod][vecin] != 0)//orice muchie are capacitate nenula
{
int dist_nou = d[nod] + cost[nod][vecin] + dvechi[nod] - dvechi[vecin];
if (dist_nou < d[vecin])
{
d[vecin] = dist_nou;
dreal[vecin] = dreal[nod] + cost[nod][vecin];
tata[vecin] = nod;
heap.push((nod_dij){vecin,dist_nou});
}
}
}
}
for (int i = 1;i <= n;++i)
dvechi[i] = dreal[i];
if (d[destinatie] == INF)
return false;
int influx = INF, cost_influx = 0;
for (int aux = destinatie;aux != sursa;aux = tata[aux])
{
if (capacitate[ tata[aux] ][aux] < influx)
influx = capacitate[ tata[aux] ][aux];
cost_influx += cost[tata[aux]][aux];
}
flux += influx;
flux_maxim_de_cost_minim += influx * dreal[destinatie];
for (int aux = destinatie;aux != sursa;aux = tata[aux])
{
capacitate[tata[aux]][aux] -= influx;
capacitate[aux][tata[aux]] += influx;
}
return true;
}
void creare_arce_pozitive()
//folosim Bellman-Ford pentru a crea toate arcele pozitive intrucat
//algoritmul lui Dijkstra nu e valid pe arce de cost negativ
{
for (int i = 1;i <= n;++i)
dvechi[i] = INF;
dvechi[sursa] = 0;
queue<int> coada;
bool in_coada[MAXN] = {0};
coada.push(sursa);
in_coada[sursa] = true;
while(!coada.empty())
{
int nod = coada.front();
in_coada[nod] = false;
coada.pop();
for (unsigned int i = 0;i < vecini[nod].size();++i)
{
int vecin = vecini[nod][i];
if(capacitate[nod][vecin] != 0)//orice muchie are capacitate nenula
{
if(dvechi[nod] + cost[nod][vecin] >= dvechi[vecin])
continue;
dvechi[vecin] = dvechi[nod] + cost[nod][vecin];
if (in_coada[vecin])
continue;
in_coada[vecin] = true;
coada.push(vecin);
}
}
}
}
int main()
{
citire();
flux = flux_maxim_de_cost_minim = 0;
creare_arce_pozitive();
while(dijkstra())
;
out << flux_maxim_de_cost_minim << '\n';
return 0;
}