Pagini recente » Cod sursa (job #134555) | Cod sursa (job #3251631) | Cod sursa (job #2132514) | Cod sursa (job #1986459) | Cod sursa (job #1557672)
/*
Flux maxim de cost minim
Complexitate:O(N*M2*logN) pentru 100 pct
D. Liviu
*/
#include <iostream>
#include <stdio.h>
#include <deque>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <cstring>
#define NMax 405
using namespace std;
const int long long Infinit=999999;
vector<int> Graf[NMax];
set<pair<int,int> > Heap;
int Cost[NMax][NMax],Capacitate[NMax][NMax],Flux[NMax][NMax];
int tata[NMax],Distance[NMax];
bool InCoada[NMax];
queue<int> Q;
int N,M,Sursa,Destinatie,capacitate,x,y,z;
void Read()
{
scanf("%d%d%d%d",&N,&M,&Sursa,&Destinatie);
for(int i=1;i<=M;i++)
{
scanf("%d%d%d%d",&x,&y,&capacitate,&z);
Graf[x].push_back(y);
Graf[y].push_back(x);
Capacitate[x][y]=capacitate;
Cost[x][y]=Cost[x][y]+z;
Cost[y][x]=Cost[y][x]-z;
}
}
inline void BellManFord(int Sursa,int Destinatie)
{
memset(Distance,Infinit,sizeof(Distance));
Q.push(Sursa);
Distance[Sursa]=0;
InCoada[Sursa]=true;
while(Q.empty()==false)
{
int nod=Q.front();
Q.pop();
InCoada[nod]=false;
for(vector<int>::iterator it=Graf[nod].begin();it!=Graf[nod].end();it++)
if(Distance[*it]>Distance[nod]+Cost[nod][*it] && Capacitate[nod][*it]>Flux[nod][*it])
{
Distance[*it]=Distance[nod]+Cost[nod][*it];
if(InCoada[*it]==false)
{
InCoada[*it]=true;
Q.push(*it);
}}}
}
void Initialization(int Sursa,int Destinatie)
{
for(int nod=1;nod<=N;nod++)
for(vector<int>::iterator it=Graf[nod].begin();it!=Graf[nod].end();it++)
if(Distance[nod]!=Infinit && Distance[*it]!=Infinit)
Cost[nod][*it]=Cost[nod][*it]+(Distance[nod]-Distance[*it]);
memset(Distance,Infinit,sizeof(Distance));
memset(tata,0,sizeof(tata));
}
bool Dijkstra(int Sursa,int Destinatie)
{
Initialization(Sursa,Destinatie);
Heap.insert(make_pair(0,Sursa));
Distance[Sursa]=0;
while(Heap.empty()==false)
{
int cost=(*Heap.begin()).first;
int nod=(*Heap.begin()).second;
Heap.erase(Heap.begin());
if(Distance[nod]!=cost) continue;
for(int i=0;i<Graf[nod].size();i++)
if(Distance[Graf[nod][i]]>Distance[nod]+Cost[nod][Graf[nod][i]] && Capacitate[nod][Graf[nod][i]]>Flux[nod][Graf[nod][i]])
{
Distance[Graf[nod][i]]=Distance[nod]+Cost[nod][Graf[nod][i]];
tata[Graf[nod][i]]=nod;
Heap.insert(make_pair(Distance[Graf[nod][i]],Graf[nod][i]));
}
}
return Distance[Destinatie]<Infinit;
}
long long EdmondsKarp(int Sursa,int Destinatie)
{
long long CostFlow=0,flow=0;
int FlowMin,DistanceFlow=Distance[Destinatie];
while(Dijkstra(Sursa,Destinatie))
{
FlowMin=Infinit;
for(int nod=Destinatie;nod!=Sursa;nod=tata[nod])
FlowMin=min(FlowMin,(Capacitate[tata[nod]][nod]-Flux[tata[nod]][nod]));
for(int nod=Destinatie;nod!=Sursa;nod=tata[nod])
{
Flux[tata[nod]][nod]=Flux[tata[nod]][nod]+FlowMin;
Flux[nod][tata[nod]]=Flux[nod][tata[nod]]-FlowMin;
}
flow=flow+FlowMin;
DistanceFlow=DistanceFlow+Distance[Destinatie];
CostFlow=CostFlow+FlowMin*DistanceFlow;
}
return CostFlow;
}
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
Read();
BellManFord(Sursa,Destinatie);
printf("%d",EdmondsKarp(Sursa,Destinatie));
}