Cod sursa(job #718815)

Utilizator ChallengeMurtaza Alexandru Challenge Data 21 martie 2012 09:44:05
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <fstream>
#include <vector>
#include <cstring>

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];
char inQ[MaxN];
bool amDrum;
vector<int> G[MaxN];

inline int BellmanFord()
{
	for(register int i=1;i<=N;++i)
	{
		Dist[i]=INF;
	}
	
	memset(inQ,0,sizeof(inQ));
	memset(From,0,sizeof(From));
	
	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;
					}
				}
			}
		}
	}
	
	if(Dist[D]!=INF)
	{
		amDrum=true;
		
		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];
		}
		
		return flow*Dist[D];
	}
	
	return 0;
}

inline int Flow()
{
	int rez=0;
	amDrum=true;
	while(amDrum)
	{
		amDrum=false;
		rez+=BellmanFord();
	}
	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;
}