Cod sursa(job #429440)

Utilizator borsoszalanBorsos Zalan borsoszalan Data 30 martie 2010 10:04:37
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include<stdio.h>
#include<vector>
#include<queue>
#include<bitset>
#define nmax 400

using namespace std;

vector<int> g[nmax];

int n, m, i, j, s, d, x, y, c, z, inf=999999, nod, act, fmin;
int cap[nmax][nmax], cost[nmax][nmax], dist[nmax], sz[nmax], tata[nmax], p[nmax];

inline int min(const int &a, const int &b)
{
    return (a < b)? a : b;
}

int minim(int a, int b)
{
	if(a>b)
		return b;
	else return a;
}

void read()
{
	scanf("%d%d%d%d", &n, &m, &s, &d);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d%d", &x, &y, &c, &z);
		g[x].push_back(y);
		g[y].push_back(x);
		cap[x][y]=c;
		cost[x][y]=z;
		cost[y][x]=-z;
	}
	for(i=1;i<=n;i++)
		sz[i]=g[i].size();
}

int Bellman()
{
	for(i=1;i<=n;i++)
		dist[i]=inf;
	bitset<nmax> viz;
	queue<int> coada;
	coada.push(s);
	dist[s]=0;
	viz[s]=0;
	for(;!coada.empty();coada.pop())
	{
		nod=coada.front();
		viz[nod]=0;
		for(i=0;i<sz[nod];i++)
		{
			act=g[nod][i];
			if(cap[nod][act]&&dist[nod]+cost[nod][act]<dist[act])
			{
				dist[act]=dist[nod]+cost[nod][act];
				tata[act]=nod;
				if(!viz[act])
				{
					coada.push(act);
					viz[act]=1;
				}
			}
		}
	}
	return (dist[d]<inf);
}

void flux()
{
	int flow=0;
	while(Bellman())
	{
		int nr=0;
		for(i=d;i>=1;i=tata[i])
			p[++nr]=i;
		fmin=inf;
		for(i=1;i<nr;i++)
			fmin=min(fmin, cap[p[i+1]][p[i]]);
		for(i=1;i<nr;i++)
		{
			cap[p[i+1]][p[i]]-=fmin;
			cap[p[i]][p[i+1]]+=fmin;
		}
		flow+=fmin*dist[d];
	}
	printf("%d\n", flow);


}


int main()
{
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	read();
	flux();
	return 0;
}