Cod sursa(job #292806)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 31 martie 2009 18:25:18
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
using namespace std;

#include <queue>
#include <bitset>

#define pb push_back
#define II inline
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define CC(v) memset((v),0,sizeof((v)))
#define mp make_pair

#define IN  "fmcm.in"
#define OUT "fmcm.out"
#define N_MAX (1<<9)
#define oo 1684300900

typedef pair<int,int> pi;

int flow,sum,rez,N,M,S,D;
int G[N_MAX],Dist[N_MAX],T[N_MAX],C[N_MAX][N_MAX],Z[N_MAX][N_MAX];
vector<int> A[N_MAX];
priority_queue<pi,vector<pi>,greater<pi> > Q;

II void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	
	int x,y,c,z;
	scanf("%d%d%d%d\n",&N,&M,&S,&D);
	FOR(i,1,M)
	{
		scanf("%d%d%d%d",&x,&y,&c,&z);
		A[x].pb(y);
		A[y].pb(x);
		C[x][y] = c;
		Z[x][y] = z;
		Z[y][x] = -z;
	}	
}

II void Dijkstra()
{
	FOR(i,1,N)
	FOR(j,0,(int)A[i].size()-1)
		if(Dist[i] != oo && Dist[ A[i][j] ] != oo)
			Z[i][ A[i][j] ] += Dist[i] - Dist[ A[i][j] ];
	memset(Dist,100,sizeof(Dist));

	Dist[S] = 0;
	++G[S];
	Q.push( mp(0,S) );
	
	for(int nod;!Q.empty();)
	{
		--G[nod = Q.top().second];
		Q.pop();
		if(G[nod])
			continue;
		
		int fiu;
		FOR(j,0,(int)A[nod].size()-1)
			if(C[nod][ fiu=A[nod][j] ] &&  Dist[fiu] > Dist[nod] + Z[nod][fiu])
			{
				Dist[fiu] = Dist[nod] + Z[nod][fiu];
				T[fiu] = nod;
				++G[fiu];
				Q.push( mp(Dist[fiu],fiu) );
			}	
	}	
}

II bool flux()
{
	Dijkstra();
	
	if(Dist[D] == (flow=oo))
		return false;
	
	for(int nod = D;T[nod];flow = min(flow,C[T[nod]][nod]),nod = T[nod]);
	for(int nod = D;T[nod];C[nod][T[nod]] += flow,C[T[nod]][nod] -= flow,nod = T[nod]);
	
	rez += (sum += Dist[D]) * flow;
	return true;
}

II void solve()
{
	for(Dijkstra(),sum += Dist[D];flux(););
	
	printf("%d\n",rez);	
}

int main()
{
	scan();
	solve();
	return 0;
}