Cod sursa(job #796118)

Utilizator radustn92Radu Stancu radustn92 Data 10 octombrie 2012 18:10:39
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <stdio.h>
#include <queue>
#include <string.h>
#include <bitset>
#include <vector>
#define NMAX 355
#define INF 1000000000
#define pb push_back
using namespace std;
int n,m,C[NMAX][NMAX],F[NMAX][NMAX],cost[NMAX][NMAX],S,D;
int best[NMAX],ant[NMAX],find_way,rez;
vector <int> A[NMAX];
queue <int> Q;
char in[NMAX];
void read()
{
	scanf("%d%d%d%d",&n,&m,&S,&D);
	int i,x,y,z,t;
	for (i=1; i<=m; i++)
	{
		scanf("%d%d%d%d",&x,&y,&z,&t);
		C[x][y]=z; cost[x][y]=t; cost[y][x]=-t;
		A[x].pb(y); A[y].pb(x);
	}
}
void init()
{
	Q.push(S); in[S]=1;
	int i;
	for (i=1; i<=n; i++)
		best[i]=INF;
	best[S]=0;
}
inline int min(int x,int y)
{
	return x<y ? x : y;
}
int flow()
{
	init();
	
	int i,nod,vec;
	while (!Q.empty())
	{
		nod=Q.front();
		Q.pop(); in[nod]=0;
		for (i=0; i<A[nod].size(); i++)
		{
			vec=A[nod][i];
			if (C[nod][vec]-F[nod][vec]>0 && best[vec]>best[nod]+cost[nod][vec])
			{
				best[vec]=best[nod]+cost[nod][vec];
				ant[vec]=nod;
				if (!in[vec])
					Q.push(vec),in[vec]=1;
			}
		}
	}
	if (best[D]!=INF)
	{
		find_way=1;
		
		int fmin=INF;
		for (nod=D; nod!=S; nod=ant[nod])
			fmin=min(fmin,C[ant[nod]][nod]-F[ant[nod]][nod]);
		for (nod=D; nod!=S; nod=ant[nod])
		{
			F[ant[nod]][nod]+=fmin;
			F[nod][ant[nod]]-=fmin;
		}
		return fmin*best[D];
	}
	return 0;
}
void solve()
{
	find_way=1;
	while (find_way)
	{
		find_way=0;
		rez+=flow();
	}
}
int main()
{
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	read();
	solve();
	printf("%d\n",rez);
	return 0;
}