Cod sursa(job #243517)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 13 ianuarie 2009 15:13:52
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
#include<stdio.h>
#define w paux->inf
#define cw C[u]+cost[u][w]
#define FR cap[T[u]][u]-flow[T[u]][u]
#define FW cap[u][w]-flow[u][w]
#define FOR_P for(paux=p[u];paux;paux=paux->urm)
#define LL long long
#define N 360
#define I 1<<30
struct nod{int inf;nod *urm;};
nod *p[N];
int n,m,s,d,u,v,ok,L,
C[N],H[N],P[N],T[N],
cap[N][N],cost[N][N],flow[N][N],ci[N][N],
bellman_ford(),djikstra();
void readd(),flux(),update(),prints(),
sw(int p1,int p2),down(int pc),up(int pc);
LL sol;
int main()
{
	readd();
	flux();
	prints();
	return 0;
}
void readd()
{       nod *paux;
	int cp,co;
	freopen("fmcm.in","rt",stdin);
	freopen("fmcm.out","wt",stdout);
	scanf("%d%d%d%d",&n,&m,&s,&d);
	for(u=1;u<=n;u++)for(v=1;v<=n;v++)cost[u][v]=I;
	for(int i=1;i<=m;i++)
	{ scanf("%d%d%d%d",&u,&v,&cp,&co);
	  cap[u][v]=cp;ci[u][v]=cost[u][v]=co;cost[v][u]=-co;
	  paux=new nod;w=v;paux->urm=p[u];p[u]=paux;
	  paux=new nod;w=u;paux->urm=p[v];p[v]=paux;
	}
}
void flux()
{
	while(bellman_ford())update();
	//while(djikstra()) update();
}
void prints()
{
	//for(u=1;u<=n;u++)
	 //for(v=1;v<=n;v++)
	  //sol+=flow[u][v]*cost[u][v];
	printf("%lld",sol);
}
int bellman_ford()
{       nod *paux;
	for(u=1;u<=n;u++)C[u]=I;C[s]=0;
	ok=1;
	while(ok)
	{ ok=0;
	  for(u=1;u<=n;u++)
	   if(C[u]<I)
	    FOR_P//for(paux=p[u];paux;paux=paux->urm)
	     if(FW)//cap[u][w]-flow[u][w])
	      if(cw<C[w])
	       { ok=1;T[w]=u;C[w]=cw;}
	}
	if(C[d]<I)return 1;
	return 0;
}
int djikstra()
{       nod *paux;
	for(u=1;u<=n;u++){C[u]=I;H[u]=u;P[u]=u;}
	C[s]=0;sw(s,1);L=1;
	for(;;)
	{ if(!L||H[1]==I)break;
	  u=H[1];sw(1,L);L--;down(1);
	  FOR_P//for(paux=p[u];paux;paux=paux->urm)
	   if(FW)//cap[u][w]-flow[u][w])
	    if(cw<C[w])
	    { C[w]=cw;T[w]=u;up(P[w]);}
	}
	if(C[d]<I)return 1;return 0;
}
void update()
{       int FL=I;nod *paux;
	for(u=d;u-s;u=T[u])FL=(FL<FR)?FL:FR;
	for(u=d;u-s;u=T[u])
	 { sol+=cost[T[u]][u]*FL;flow[T[u]][u]+=FL;flow[u][T[u]]-=FL;}
	//for(u=1;u<=n;u++)
	 //FOR_P
	  //if(C[u]<I&&C[w]<I)cost[u][w]+=C[u]-C[w];
}
void sw (int p1,int p2)
{
	int aux=H[p1];H[p1]=H[p2];H[p2]=aux;
	P[H[p1]]=p1;P[H[p2]]=p2;
}
void down(int pc)
{ int pf=pc<<1;
  if(pf>L)return;
  if(pf<L)pf=(C[H[pf]]<C[H[pf+1]])?pf:pf+1;
  if(C[H[pf]]<C[H[pc]]){sw(pf,pc);down(pf);}
}
void up(int pc)
{
	int pt=pc>>1;
	if(!pt||C[H[pt]]<=C[H[pc]])return;
	sw(pc,pt);up(pt);
}