Cod sursa(job #428335)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 29 martie 2010 10:09:32
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.85 kb
#include<stdio.h>
#include<vector>
#include<queue>
#define Inf 1<<30
#define Nmax 400
#define Min(a,b) a<b ? a : b
using namespace std;
int C[Nmax][Nmax],F[Nmax][Nmax],Cmin[Nmax],Cost[Nmax][Nmax],poz[Nmax],H[Nmax],T[Nmax];
bool in_queue[Nmax],drum=true;
int i,n,m,S,D,cap,cst,Sum,L,a,b;
vector<int> V[Nmax];
queue<int> Q;

void swap(int i, int j)
{
	poz[H[i]]=j;
	poz[H[j]]=i;
	int aux=H[i]; H[i]=H[j]; H[j]=aux;
}

int pozmin(int i)
{
	int k=i<<1;
	if(k+1<=L)
		if(Cmin[H[k+1]]<Cmin[H[k]]) return k+1;
	return k;
}

void down(int i)
{
	int k;
	if(i<=(L>>1))
	{
		k=pozmin(i);
		if(Cmin[H[k]]<Cmin[H[i]])
		{
			swap(i,k);
			down(k);
		}
	}
}

void up(int i)
{
	int k=i>>1;
	if(i>1)
	{
		if(Cmin[H[i]]<Cmin[H[k]])
		{
			swap(i,k);
			up(k);
		}
	}
}

void push(int x)
{
	H[++L]=x;
	poz[x]=L;
	up(L);
}

void pop()
{
	swap(1,L);
	poz[H[L]]=0;
	H[L--]=0;
	down(1);
}

void BellmanFord()
{
	int p,u,i,N,nod,fiu,cost;
	
	for(i=1;i<=n;i++)
		Cmin[i]=Inf;
	Cmin[S]=0;
	
	Q.push(S);
	in_queue[S]=true;
	
	for(p=u=1;p<=u;p++)
	{
		nod=Q.front();
		Q.pop();
		in_queue[nod]=false;
		N=V[nod].size();
		
		for(i=0;i<N;i++)
		{
			fiu=V[nod][i];
			cost=Cost[nod][fiu];
			
			if(C[nod][fiu] && Cmin[fiu] > Cmin[nod]+cost)
			{
				Cmin[fiu]=Cmin[nod]+cost;
				if(in_queue[fiu]==false)
				{
					in_queue[fiu]=true;
					Q.push(fiu);
					u++;
				}
			}
		}
	}
	Sum=Cmin[D];
}
 	
int Dijkstra()
{
	int i,N,nod,fiu,cost,r;
	
	for(nod=1;nod<=n;nod++)
	{
		N=V[nod].size();
		
		for(i=0;i<N;i++)
		{
			fiu=V[nod][i];
			if(Cmin[nod]!=Inf && Cmin[fiu]!=Inf)
				Cost[nod][fiu]+=Cmin[nod]-Cmin[fiu];
		}
	}
	
	for(i=1;i<=n;i++)
	{
		Cmin[i]=Inf;
		poz[i]=0;
		T[i]=0;
		H[i]=0;
	}
	poz[S]=1; H[1]=S; L=1; Cmin[S]=0;
		
	while(L)
	{
		nod=H[1];
		pop();
		N=V[nod].size();
		
		for(i=0;i<N;i++)
		{
			fiu=V[nod][i];
			cost=Cost[nod][fiu];
			
			if( Cmin[fiu] > Cmin[nod]+cost && C[nod][fiu]!=F[nod][fiu] )
			{
				Cmin[fiu]=Cmin[nod]+cost;
				T[fiu]=nod;
				if(!poz[fiu]) push(fiu);
				else up(poz[fiu]);
			}
		}
	}
	
	if(Cmin[D]!=Inf)
	{
		drum=true;
		r=Inf;
		
		for(i=D; i!=S; i=T[i])
			r=Min(r,C[T[i]][i]-F[T[i]][i]);
		
		for(i=D; i!=S; i=T[i])
		{
			F[T[i]][i]+=r;
			F[i][T[i]]-=r;
		}
		
		Sum+=Cmin[D];
		return r*Sum;
	}
		
	return 0;
}
	
long long fmcm()
{
	long long flux=0;
		
	while(drum==true)
	{
		drum=false;
		flux+=Dijkstra();
	}
	return flux;
}

int main()
{
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	
	scanf("%d %d %d %d",&n,&m,&S,&D);
	
	for(i=1;i<=m;i++)
	{
		scanf("%d %d %d %d",&a,&b,&cap,&cst);
		V[a].push_back(b);
		V[b].push_back(a);
		
		C[a][b]=cap;
		Cost[a][b]=cst;
		Cost[b][a]=-cst;
	}
	
	BellmanFord();
	
	printf("%lld",fmcm());
	
	return 0;
}