Pagini recente » Sandbox (cutiuţa cu năsip) | Cod sursa (job #2373540) | Cod sursa (job #2066147) | Cod sursa (job #1686813) | Cod sursa (job #1870074)
/// Calcularea costului minim pt. a obtine un flux maxim pe un graf orientat
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
const int MAX = 355;
const int Inf = 0x3f3f3f3f;
struct Nod{
int cost, nod;
bool operator < ( const Nod& a ) const
{
return cost > a.cost;
}
};
using VI = vector<int>;
vector<VI> G;
int N, M, S, D;
int m[MAX][MAX];
int C[MAX][MAX];
int Cost[MAX]; /// costul curent
int P[MAX]; /// costul precedent
int RealCost[MAX]; /// costul curent real
int t[MAX];
int cmin;
void ReadGraph();
void Bellman_Ford();
bool Dijkstra();
int main()
{
ReadGraph();
Bellman_Ford();
/* for ( int i = 1; i <= N; ++i )
fout << P[i] << ' '; */
while ( Dijkstra() );
fout << cmin << '\n';
fin.close();
fout.close();
return 0;
}
void ReadGraph()
{
int x, y, z, t;
fin >> N >> M >> S >> D;
G = vector<VI>(N + 1);
while ( M-- )
{
fin >> x >> y >> z >> t;
G[x].push_back(y);
G[y].push_back(x);
m[x][y] = t;
m[y][x] = -t;
C[x][y] = z;
C[y][x] = 0;
}
}
void Bellman_Ford()
{
queue<int> Q;
memset( P, Inf, sizeof(P) );
P[S] = 0;
Q.push(S);
while ( !Q.empty() )
{
int x = Q.front();
Q.pop();
for ( const int& y : G[x] )
if ( C[x][y] )
{
int cost_nou = P[x] + m[x][y];
if ( cost_nou >= P[y] )
continue;
P[y] = cost_nou;
Q.push(y);
}
}
}
bool Dijkstra()
{
priority_queue<Nod> Q;
memset(Cost, Inf, sizeof(Cost));
Cost[S] = RealCost[S] = 0;
Q.push({0, S});
while ( !Q.empty() )
{
int x = Q.top().nod;
int c0 = Q.top().cost;
Q.pop();
if ( c0 != Cost[x] ) continue;
for ( const int& y : G[x] )
if ( C[x][y] )
{
int cost_nou = Cost[x] + P[x] + m[x][y] - P[y];
if ( cost_nou >= Cost[y] )
continue;
Cost[y] = cost_nou;
RealCost[y] = RealCost[x] + m[x][y];
t[y] = x;
Q.push({Cost[y], y});
}
}
memcpy(P, Cost, sizeof(Cost));
if ( Cost[D] >= Inf ) return false;
int fc = Inf;
for ( int i = D; i != S; i = t[i] )
fc = min( fc, C[t[i]][i] );
cmin += fc * RealCost[D];
for ( int i = D; i != S; i = t[i] )
{
C[t[i]][i] -= fc;
C[i][t[i]] += fc;
}
return true;
}