Pagini recente » Cod sursa (job #2352725) | Cod sursa (job #1075214) | Cod sursa (job #3127063) | Cod sursa (job #1978820) | Cod sursa (job #777231)
Cod sursa(job #777231)
// Problema fluxului maxim de cost minim este o problema a
// categoriei fluxului si functioneaza pe acelasi principiu.
// O vom rezolva in acelasi fel cu moduficarea ca folosim un
// algoritm de determinare a drumului de cost minim.
// Cel mai convenabil din punct de vedere implementare/eficienta este
// Bellman-Ford. Complexitatea teoretica este O(N*N*M*M).
// Complexitatea este supraestimata , iar complexitatea optima este cea
// a algoritmului lui Dijkstra: O(N*M*M*lg N).
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int Nmax = 355;
const int Mmax = 12511;
const int oo = 1<<30;
int Flux[Nmax][Nmax];
int Cost[Nmax][Nmax];
vector< int > Leg[Nmax];
queue< int > Q;
int N,M,Start,End;
int Rez,Drum;
int Dist[Nmax],Dad[Nmax],Used[Nmax];
ifstream F("fmcm.in");
ofstream G("fmcm.out");
int Bellman()
{
for (int i=1;i<=N;++i)
{
Dad[i]=-1;
Dist[i]=oo;
}
Dist[Start] = 0;
Q.push( Start );
memset(Used, 0, sizeof(Used));
Used[Start] = 1;
while ( Q.size() )
{
int i = Q.front();
for (int j=0;j<int( Leg[i].size() );++j)
if ( Flux[i][Leg[i][j]] > 0 && Dist[i] + Cost[i][Leg[i][j]] < Dist[Leg[i][j]] )
{
Dist[ Leg[i][j] ] = Dist[i] + Cost[i][ Leg[i][j] ];
Dad[ Leg[i][j] ] = i;
if ( !Used[ Leg[i][j] ] )
{
Q.push( Leg[i][j] );
Used[ Q.back() ] = 1;
}
}
Q.pop();
Used[i]=0;
}
if ( Dist[End] != oo )
{
int Vmin = oo;
Drum = 1;
for (int i = End; i != Start; i = Dad[i])
Vmin = min(Vmin, Flux[Dad[i]][i] );
for (int i = End; i != Start; i = Dad[i])
{
Flux[Dad[i]][i] -= Vmin;
Flux[i][Dad[i]] += Vmin;
}
return Vmin * Dist[End];
}
return 0;
}
int main()
{
F>>N>>M>>Start>>End;
for (int i=1;i<=M;++i)
{
int x,y,cap,cos;
F>>x>>y>>cap>>cos;
Flux[x][y]=cap;
Cost[x][y]=cos;
Cost[y][x]=-cos;
Leg[x].push_back( y );
Leg[y].push_back( x );
}
Rez=0;
Drum=1;
while ( Drum )
{
Drum=0;
Rez+=Bellman();
}
G<<Rez<<'\n';
}