Pagini recente » Cod sursa (job #3237800) | Cod sursa (job #655909) | Cod sursa (job #517696) | Cod sursa (job #3273702) | Cod sursa (job #2749713)
/// 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;
using VI = vector<int>;
struct Nod{
int cost, nod;
bool operator < ( const Nod& a ) const
{
return cost > a.cost;
}
};
class Graph{
public:
int getMinCost()
{
Bellman_Ford();
while ( Dijkstra() );
return cmin;
}
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] )
{
Cost[y] = cost_nou;
RealCost[y] = RealCost[x] + m[x][y];
t[y] = x;
Q.push({Cost[y], y});
}
}
}
memcpy(P, RealCost, sizeof(RealCost));
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;
}
vector<VI> G;
int N, 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;
};
Graph G;
int M;
void ReadGraph();
void Bellman_Ford();
bool Dijkstra();
int main()
{
ReadGraph();
/* for ( int i = 1; i <= N; ++i )
fout << P[i] << ' '; */
fout << G.getMinCost() << '\n';
fin.close();
fout.close();
return 0;
}
void ReadGraph()
{
int x, y, z, t;
fin >> G.N >> M >> G.S >> G.D;
G.G = vector<VI>(G.N + 1);
while ( M-- )
{
fin >> x >> y >> z >> t;
G.G[x].push_back(y);
G.G[y].push_back(x);
G.m[x][y] = t;
G.m[y][x] = -t;
G.C[x][y] = z;
G.C[y][x] = 0;
}
}