Cod sursa(job #292606)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 31 martie 2009 12:15:55
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
using namespace std;

#include <set>
#include <map>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <utility>
#include <algorithm>

#define pb push_back
#define sz size
#define f first
#define s second
#define II inline
#define ll long long
#define db double
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define all(v) v.begin() , v.end()
#define CC(v) memset((v),0,sizeof((v)))
#define CP(v,w) memcpy((v),(w),sizeof((w)))
#define mp make_pair

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

typedef vector<int> VI;
typedef pair<int,int> pi;
typedef vector<string> VS;

int N,M,S,D;
int G[N_MAX],Cd[N_MAX],T[N_MAX],Ci[N_MAX][N_MAX],C[N_MAX][N_MAX],Z[N_MAX][N_MAX];
vector<VI> A(N_MAX);

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);
		C[x][y] = Ci[x][y] = c;
		Z[x][y] = z + Zmin;
	}	
}

priority_queue<int,VI,greater<int> > Q;

II void Dijkstra()
{
	CC(T);CC(G);
	memset(Cd,50,sizeof(Cd));
	Cd[S] = 0;
	G[S] = 1;
	Q.push(S);
	
	for(int nod;!Q.empty();)
	{
		nod = Q.top();
		Q.pop();
		--G[nod];
		if(G[nod])
			continue;
		
		FOR(j,0,(int)A[nod].sz()-1)
		{
			int fiu = A[nod][j];
			if(C[nod][fiu] &&  Cd[fiu] > Cd[nod] + Z[nod][fiu])
			{
				Cd[fiu] = Cd[nod] + Z[nod][fiu];
				T[fiu] = nod;
				++G[fiu];
				Q.push(fiu);
			}	
		}	
	}	
}

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

II void solve()
{
	for(;flux(););
	
	int rez(0);
	FOR(i,1,N)
	FOR(j,0,(int)A[i].sz()-1)
	{
		int fiu = A[i][j];
		rez += (Z[i][fiu] - Zmin) * (Ci[i][fiu] - C[i][fiu]);
	}
	printf("%d\n",rez);	
}

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