Cod sursa(job #244133)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 14 ianuarie 2009 16:58:56
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.88 kb
#include<stdio.h>
#define N 360
struct nod{int inf;nod *urm;};
nod *p[N],*paux;
int n,m,s,d,i,xx,yy,cc,vv,ok,j,lheap,nc,nv,dc,dv,fd,cd,fm,
i8=2000000000,
cap[N][N],cost[N][N],flow[N][N],dad[N],heap[N],poz[N],val[N],
djikstra();
long long sol,lf,lc;
void readd(),bellman_ford(),flux(),update(),
sw(int i1,int i2),heap_up(int fiu),heap_down(int tata);
int main()
{
	readd();
	bellman_ford();
	flux();
	return 0;
}
void readd()
{
	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",&xx,&yy,&cc,&vv);
	  paux=new nod;paux->inf=xx;paux->urm=p[yy];p[yy]=paux;
	  paux=new nod;paux->inf=yy;paux->urm=p[xx];p[xx]=paux;
	  cap[xx][yy]=cc;cost[xx][yy]=vv;cost[yy][xx]=-vv;
	}
}
void bellman_ford()
{
	for(i=1;i<=n;i++){val[i]=i8;dad[i]=0;}val[s]=0;
	ok=1;
	while(ok)
	{       ok=0;
		for(i=1;i<=n;i++)
		{ if(val[i]==i8)continue;
		  for(paux=p[i];paux;paux=paux->urm)
		   {  j=paux->inf;
		      if(cap[i][j]-flow[i][j])
		       if(val[j]>val[i]+cost[i][j])
		       { val[j]=val[i]+cost[i][j];
			 dad[j]=i;ok=1;
		       }
		   }
		}
	}
	lc=val[d];
}
void flux()
{
	while(djikstra());//update();
	printf("%lld\n",sol);
}
int djikstra()
{
      for(i=1;i<=n;i++)
       for(paux=p[i];paux;paux=paux->urm)
	  if(val[i]<i8&&val[paux->inf]<i8)
	    cost[i][paux->inf]+=val[i]-val[paux->inf];
      for(i=1;i<=n;i++) { val[i]=i8;heap[i]=i;poz[i]=i;dad[i]=0;}
      val[s]=0;lheap=n;sw(1,s);
      while(lheap>1&&val[heap[1]]<i8)
      {  nc=heap[1];dc=val[nc];
	 for(paux=p[nc];paux;paux=paux->urm)
	 { nv=paux->inf;
	   if(cap[nc][nv]-flow[nc][nv]>0)
	     { dv=dc+cost[nc][nv];
	       if(dv<val[nv])
	       { val[nv]=dv;
		 dad[nv]=nc;
		 heap_up(poz[nv]);
	       }
	     }
	 }
	 sw(1,lheap);
	 lheap--;
	 heap_down(1);
      }
      if(val[d]==i8)return 0;
      fd=i8;cd=0;
	for(i=d;dad[i];i=dad[i])
	{ fm=cap[dad[i]][i]-flow[dad[i]][i];
	  fd=(fm<fd)?fm:fd;
	  //cd+=cost[dad[i]][i];
	}
	lf=(long long)fd;
	lc+=(long long)val[d];
	sol+=lf*lc;
	for(i=d;dad[i];i=dad[i])
	{ flow[dad[i]][i]+=fd;flow[i][dad[i]]-=fd;}
      return 1;
}
void update()
{       fd=i8;cd=0;
	for(i=d;dad[i];i=dad[i])
	{ fm=cap[dad[i]][i]-flow[dad[i]][i];
	  fd=(fm<fd)?fm:fd;
	  //cd+=cost[dad[i]][i];
	}
	lf=(long long)fd;
	lc+=(long long)val[d];
	sol+=lf*lc;
	for(i=d;dad[i];i=dad[i])
	{ flow[dad[i]][i]+=fd;flow[i][dad[i]]-=fd;}
}
void heap_up(int fiu)
{ int tata=fiu>>1;
  if(!tata||val[heap[tata]]<=val[heap[fiu]])return;
  sw(fiu,tata);heap_up(tata);
}
void heap_down(int tata)
{
	int fiu=tata<<1;
	if(fiu>lheap)return;
	if(fiu<lheap) if(val[heap[fiu+1]]<val[heap[fiu]])fiu++;
	if(val[heap[tata]]>val[heap[fiu]]){sw(fiu,tata);heap_down(fiu);}
}
void sw(int i1,int i2)
{
	int aux=heap[i1];heap[i1]=heap[i2];heap[i2]=aux;
	poz[heap[i1]]=i1;poz[heap[i2]]=i2;
}