Cod sursa(job #718872)

Utilizator ChallengeMurtaza Alexandru Challenge Data 21 martie 2012 10:41:04
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.52 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <set>

using namespace std;

const char InFile[]="fmcm.in";
const char OutFile[]="fmcm.out";
const int MaxN=355;
const int INF=1<<30;

ifstream fin(InFile);
ofstream fout(OutFile);

short int N,M,S,D,x,y,c,z,From[MaxN],Q[MaxN*MaxN],C[MaxN][MaxN],F[MaxN][MaxN],Cost[MaxN][MaxN];
int qst,qsf,Dist[MaxN],sumDist;
char inQ[MaxN];

struct Cmp
{
	bool operator() (const int &a, const int &b)
	{
		if(Dist[a]==Dist[b])
		{
			return a<b;
		}
		return Dist[a]<Dist[b];
	}
};

vector<int> G[MaxN];
set<int,Cmp> H;

inline void BellmanFord()
{
	for(register int i=1;i<=N;++i)
	{
		Dist[i]=INF;
	}
	
	qst=qsf=1;
	Dist[S]=0;
	Q[1]=S;
	inQ[S]=1;
	while(qst<=qsf)
	{
		int nod=Q[qst];
		++qst;
		inQ[nod]=0;
		for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
		{
			if(C[nod][*it]-F[nod][*it])
			{
				if(Dist[*it]>Dist[nod]+Cost[nod][*it])
				{
					Dist[*it]=Dist[nod]+Cost[nod][*it];
					From[*it]=nod;
					if(!inQ[*it])
					{
						Q[++qsf]=*it;
						inQ[*it]=1;
					}
				}
			}
		}
	}
	sumDist=Dist[D];
}

inline void Dijkstra()
{	
	for(register int i=1;i<=N;++i)
	{
		Dist[i]=INF;
	}
	
	Dist[S]=0;
	H.insert(S);
	
	while(!H.empty())
	{
		int nod=*H.begin();
		H.erase(H.begin());
		for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
		{
			if(C[nod][*it]-F[nod][*it])
			{
				if(Dist[*it]>Dist[nod]+Cost[nod][*it])
				{
					Dist[*it]=Dist[nod]+Cost[nod][*it];
					From[*it]=nod;
					H.erase(*it);
					H.insert(*it);
				}
			}
		}
	}
}

inline int AugmentedPath()
{
	int flow=INF;
	
	int t=D;
	while(t!=S)
	{
		flow=min(flow,C[From[t]][t]-F[From[t]][t]);
		t=From[t];
	}
	
	t=D;
	while(t!=S)
	{
		F[From[t]][t]+=flow;
		F[t][From[t]]-=flow;
		t=From[t];
	}
	
	sumDist+=Dist[D];
	return flow*sumDist;
}

inline void UpdateEdges()
{
	for(int i=1;i<=N;++i)
	{
		for(vector<int>::iterator it=G[i].begin();it!=G[i].end();++it)
		{
			Cost[i][*it]+=Dist[i]-Dist[*it];
		}
	}
}

inline int Flow()
{
	BellmanFord();
	
	int rez=0;
	while(1)
	{
		UpdateEdges();
		Dijkstra();
		if(Dist[D]!=INF)
		{
			rez+=AugmentedPath();
		}
		else
		{
			break;
		}
	}
	return rez;
}

int main()
{
	fin>>N>>M>>S>>D;
	for(register int i=1;i<=M;++i)
	{
		fin>>x>>y>>c>>z;
		G[x].push_back(y);
		G[y].push_back(x);
		
		C[x][y]=c;
		Cost[x][y]=z;
		Cost[y][x]=-z;
	}
	fin.close();
	
	fout<<Flow();
	fout.close();
	return 0;
}