Cod sursa(job #581318)

Utilizator antoanelaAntoanela Siminiuc antoanela Data 13 aprilie 2011 23:48:18
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include <cstdio>
#include <vector>
#include <set>
using namespace std;
#define nmax 260
#define inf 1<<30

int N, M, S, D, dist[nmax], c[nmax][nmax], cost[nmax][nmax], f[nmax][nmax], sol, len, t[nmax];
vector <int> g[nmax];
set <pair <int, int> > s;

void bellmanford()
{
	int i, j, k, ok=0;
	for (i=1; i<=N; i++) dist[i]=inf;
	dist[S]=0;
	for (i=1; i<=N && !ok; i++)
	{
		ok=1;
		for (j=1; j<=N; j++)
			for (k=0; k<g[j].size(); k++)
				if (c[j][g[j][k]]>0 && dist[j]+cost[j][g[j][k]]<dist[g[j][k]])
				{
					ok=0;
					dist[g[j][k]]=dist[j]+cost[j][g[j][k]];
				}
	}
	len=dist[D];
}

int dijkstra()
{
	int i, val, nod, j;
	for (i=1; i<=N; i++)
		for (j=0; j<g[i].size(); j++)
			if (dist[i] != inf && dist[g[i][j]]!=inf)
				cost[i][g[i][j]] += dist[i]-dist[g[i][j]];
	for (i=1; i<=N; i++) dist[i]=inf;
	dist[S]=0;
	s.insert(make_pair(0,S));
	while (s.size()>0)
	{
		val=(*s.begin()).first;
		nod=(*s.begin()).second;
		s.erase(*s.begin());
		for (i=0; i<g[nod].size(); i++)
		{
			if (c[nod][g[nod][i]]!=f[nod][g[nod][i]])
				if (val+cost[nod][g[nod][i]] < dist[g[nod][i]])
				{
					dist[g[nod][i]] = val+cost[nod][g[nod][i]];
					s.insert (make_pair(dist[g[nod][i]], g[nod][i]));
					t[g[nod][i]] = nod;
				}
		}
	}
	len+=dist[D];
	return dist[D]!=inf;
}

void flux()
{
	int nod, fm;
	while (dijkstra())
	{
		nod=D;
		fm=inf;
		while (t[nod])
		{
			fm=min(fm, c[t[nod]][nod]-f[t[nod]][nod]);
			nod=t[nod];
		}
		nod=D;
		while (t[nod])
		{
			f[t[nod]][nod]+=fm;
			f[nod][t[nod]]-=fm;
			nod=t[nod];
		}
		sol+=len*fm;
	}
}

int main()
{
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	scanf("%d %d %d %d", &N, &M, &S, &D);
	int i, j, x, y, cap, z;
	for (i=1; i<=M; i++)
	{
		scanf("%d %d %d %d", &x, &y, &cap, &z);
		g[x].push_back(y);
		g[y].push_back(x);
		c[x][y]=cap;
		cost[x][y]=z;
		cost[y][x]=-z;
	}
	
	bellmanford();
	flux();
	printf("%d\n",sol);
}