Cod sursa(job #292864)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 31 martie 2009 18:58:07
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 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 Dist[N_MAX],T[N_MAX],C[N_MAX][N_MAX],Z[N_MAX][N_MAX];
bool viz[N_MAX];
vector<int> A[N_MAX];

struct Comp{ bool operator() (int i,int j) {return Dist[i] > Dist[j];}};
priority_queue<int,vector<int>,Comp> 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()
{
	vector<int> :: iterator it;
	FOR(i,1,N)
	for (it = A[i].begin(); it != A[i].end(); it++)
		if(Dist[i] != oo && Dist[*it] != oo)
			Z[i][*it] += Dist[i] - Dist[*it];
	memset(Dist,100,sizeof(Dist));
	
	Dist[S] = 0;
	viz[S] = true;
	Q.push(S);
	
	for(int nod;!Q.empty();)
	{
		nod = Q.top();
		Q.pop();
		viz[nod] = false;
		
		int fiu;
		for (it = A[nod].begin(); it != A[nod].end(); it++)
			if(C[nod][*it] &&  Dist[*it] > Dist[nod] + Z[nod][*it])
			{
				Dist[*it] = Dist[nod] + Z[nod][*it];
				T[*it] = nod;
				
				if(!viz[*it])
				{
					viz[*it] = true;
					Q.push(*it);
				}	
			}	
	}	
}

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;
}

int main()
{
	scan();
	for(Dijkstra(),sum += Dist[D];flux(););
	printf("%d\n",rez);	
	
	return 0;
}