Cod sursa(job #468442)

Utilizator ionutz32Ilie Ionut ionutz32 Data 3 iulie 2010 17:30:38
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <stdio.h>

struct nod
{
	int nr,nod1,cap,f,cost;
	nod *adr,*rev;
} *graf[355],*u,*v,*tt[355];
int i,n,m,s,d,x,y,c,z,heap[355],poz[355],aux,first,min[355];
long long dist[355],cost;
bool k;

inline void heap_up(int p)
{
	while (p>1 && dist[heap[p]]<dist[heap[p>>1]])
	{
		aux=heap[p];
		heap[p]=heap[p>>1];
		heap[p>>1]=aux;
		poz[heap[p]]=p;
		poz[heap[p>>1]]=p>>1;
		p>>=1;
	}
}

inline void heap_down(int p)
{
	int min;
	while ((p*2<=x && dist[heap[p]]>dist[heap[p*2]]) || (p*2+1<=x && dist[heap[p]]>dist[heap[p*2+1]]))
	{
		if (p*2+1<=x)
			if (dist[heap[p*2]]<dist[heap[p*2+1]])
				min=p*2;
			else
				min=p*2+1;
		else
			min=p*2;
		aux=heap[p];
		heap[p]=heap[min];
		heap[min]=aux;
		poz[heap[p]]=p;
		poz[heap[min]]=min;
		p=min;
	}
}

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",&x,&y,&c,&z);
		u=new nod;
		u->nr=y;
		u->nod1=x;
		u->cap=c;
		u->cost=z;
		u->f=0;
		u->adr=graf[x];
		graf[x]=u;
		v=new nod;
		v->nr=x;
		v->nod1=y;
		v->cap=0;
		v->cost=-z;
		v->f=0;
		v->adr=graf[y];
		graf[y]=v;
		u->rev=v;
		v->rev=u;
	}
	k=true;
	while (k)
	{
		k=false;
		poz[1]=0;
		dist[1]=1LL*13000*10000000;
		for (i=2;i<=n;++i)
		{
			poz[i]=0;
			dist[i]=dist[i-1];
		}
		x=1;
		heap[1]=s;
		poz[s]=1;
		dist[s]=0;
		min[s]=2147000000;
		while (x)
		{
			first=heap[1];
			if (first==d)
				k=true;
			poz[heap[1]]=0;
			if (x==1)
				x=0;
			else
			{
				heap[1]=heap[x--];
				heap_down(1);
			}
			for (u=graf[first];u;u=u->adr)
				if (u->cap>u->f && dist[first]+u->cost<dist[u->nr])
				{
					if (min[first]<u->cap-u->f)
						min[u->nr]=min[first];
					else
						min[u->nr]=u->cap-u->f;
					dist[u->nr]=dist[first]+u->cost;
					tt[u->nr]=u;
					if (poz[u->nr])
						heap_up(poz[u->nr]);
					else
					{
						heap[++x]=u->nr;
						poz[heap[x]]=x;
						heap_up(x);
					}
				}
		}
		if (k)
			for (u=tt[d];u;u=tt[u->nod1])
			{
				u->f+=min[d];
				u->rev->f-=min[d];
				cost+=min[d]*u->cost;
			}
	}
	printf("%lld",cost);
	return 0;
}