Cod sursa(job #529275)

Utilizator PlayLikeNeverB4George Marcus PlayLikeNeverB4 Data 4 februarie 2011 17:00:29
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <stdio.h>
#define maxn 356
#define oo 2000000

struct nod {
	int inf;
	nod *next;
} *A[maxn];

int i,N,M,st,dest,hp,S,R;
int C[maxn][maxn],D[maxn],Cost[maxn][maxn],from[maxn],H[maxn],poz[maxn];

void citire()
{
	nod *q; int x,y,c,z;
	scanf("%d %d %d %d",&N,&M,&st,&dest);
	for(i=1;i<=M;i++)
	{
		scanf("%d %d %d %d",&x,&y,&c,&z);
		q=new nod; q->inf=y; q->next=A[x]; A[x]=q;
		q=new nod; q->inf=x; q->next=A[y]; A[y]=q;
		C[x][y]=c; Cost[x][y]=z; Cost[y][x]=-z;
	}
}

void BF(int sursa)
{
	nod *prim,*ultim,*nou,*aux; int pi,ps,k; pi=ps=1;
	prim=new nod; ultim=new nod;
	prim->inf=sursa; ultim=prim;
	for(i=1;i<=N;i++) D[i]=oo;
	D[sursa]=0;
	while(ps<=pi)
	{
		k=prim->inf;
		for(nod *q=A[k];q;q=q->next)
			if(C[k][q->inf]>0 && D[k]+Cost[k][q->inf]<D[q->inf])
			{
				pi++;
				D[q->inf]=D[k]+Cost[k][q->inf];
				nou=new nod;
				nou->inf=q->inf;
				ultim->next=nou;
				ultim=nou;
			}
		aux=prim; 
		prim=prim->next; 
		delete(aux); 
		ps++;
	}
	S=D[dest];
}

void costuri_poz()
{
	for(i=1;i<=N;i++)
		for(nod *q=A[i];q;q=q->next)
			if(D[i]!=oo && D[q->inf]!=oo)
				Cost[i][q->inf]=Cost[i][q->inf]+D[i]-D[q->inf];
}

inline int min(int a, int b)
{
	if(a>b) return b;
	return a;
}
void swap(int &a,int &b)
{
	int aux=a;
	a=b;
	b=aux;
}
void downheap(int k)
{
	int son;
	do
	{
		son=0;
		if(2*k<=hp)
		{
			son=hp;
			if(son+1<=hp && D[H[son+1]]<D[H[son]])
				son++;
			if(D[H[son]]>D[H[k]]) son=0;
		}
		if(son)
		{
			swap(poz[H[k]],poz[H[son]]);
			swap(H[k],H[son]);
			k=son;
		}
	}
	while(son);
}
void upheap(int k)
{
	while(k>1 && D[H[k]]<D[H[k/2]])
	{
		swap(poz[H[k]],poz[H[k/2]]);
		swap(H[k],H[k/2]);
		k=k/2;
	}
}
void insert(int k)
{
	H[++hp]=k;
	poz[k]=hp;
	upheap(hp);
}
int radacina()
{
	int r=H[1];
	H[1]=H[hp];
	poz[H[1]]=1;
	hp--;
	return r;
}

int dijk()
{
	int k;
	costuri_poz();
	for(i=1;i<=N;i++) { D[i]=oo; poz[i]=0; }
	hp=0; D[st]=0; insert(st);
	while(hp)
	{
		k=radacina();
		for(nod *q=A[k];q;q=q->next)
			if(C[k][q->inf]>0 && D[k]+Cost[k][q->inf]<D[q->inf])
			{
				D[q->inf]=D[k]+Cost[k][q->inf];
				from[q->inf]=k;
				if(poz[q->inf]==0)
					insert(q->inf);
				else upheap(poz[q->inf]);
			}
	}
	if(D[dest]!=oo) return 1;
	return 0;
}

int main()
{
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	citire();
	BF(st);
	while(dijk())
	{
		int k=dest,fmin=oo;
		S+=D[dest];
		do
		{
			fmin=min(fmin,C[from[k]][k]);
			k=from[k];
		}
		while(k!=st);
		k=dest;
		do
		{
			C[from[k]][k]-=fmin;
			C[k][from[k]]+=fmin;
			k=from[k];
		}
		while(k!=st);
		R+=fmin*S;
	}
	printf("%d",R);
}