Pagini recente » Cod sursa (job #2634395) | Cod sursa (job #1675839) | Cod sursa (job #2674105) | Cod sursa (job #1419158) | Cod sursa (job #1159663)
// O(N*M^2*LogN)
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define Nmax 355
#define oo 2000000000
#define pb push_back
#define x first
#define y second
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int N,M,Source,Sink,x,y,c,z,MaxFlow,CostMin;
int cap[Nmax][Nmax],cost[Nmax][Nmax],flow[Nmax][Nmax],ante[Nmax],d[Nmax],old_d[Nmax],real_d[Nmax];
vector < int > G[Nmax];
typedef pair<int,int> PP;
priority_queue < PP , vector < PP > , greater<PP> > pq;
inline void ReadInput()
{
f>>N>>M>>Source>>Sink;
for(int i=1;i<=M;++i)
{
f>>x>>y>>c>>z;
G[x].pb(y) , G[y].pb(x);
cap[x][y]=c;
cost[x][y]=z , cost[y][x]=-z;
}
}
int Dijkstra(int Source)
{
for(int i=1;i<=N;++i)d[i]=oo,ante[i]=oo;
d[Source]=0 , ante[Source]=Source;
for(pq.push(PP(0,Source)); !pq.empty();)
{
int val=pq.top().x,node=pq.top().y;
pq.pop();
if(d[node]<val)continue;
for(vector<int>::iterator it=G[node].begin();it!=G[node].end();++it)
if(flow[node][*it]<cap[node][*it])
{
int aux=d[node]+cost[node][*it]+old_d[node]-old_d[*it];
if(aux<d[*it])
{
d[*it]=aux , ante[*it] = node;
real_d[*it]=real_d[node]+cost[node][*it];
pq.push( PP(d[*it] , *it) );
}
}
}
for(int i=1;i<=N;++i)old_d[i]=real_d[i];
return (d[Sink]!=oo) ;
}
void GetFMCM()
{
for( ; Dijkstra(Source) ; )
{
int MinFlow=oo;
for(int i=Sink; i!=Source ; i=ante[i])
MinFlow=min(MinFlow,cap[ante[i]][i]-flow[ante[i]][i]);
if(MinFlow)
{
for(int i=Sink; i!=Source ; i=ante[i])
{
flow[ante[i]][i]+=MinFlow;
flow[i][ante[i]]-=MinFlow;
}
MaxFlow+=MinFlow;
CostMin+=MinFlow*real_d[Sink];
}
}
g<<CostMin<<'\n';
}
int main()
{
ReadInput();
GetFMCM();
f.close();g.close();
return 0;
}