Cod sursa(job #290401)

Utilizator AndreyPAndrei Poenaru AndreyP Data 27 martie 2009 21:23:57
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.21 kb
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define list vector
#define pb push_back
#define fs first
#define sc second
#define mp make_pair
#define ll long long
#define N 353
const int inf=2147483647;
int n,m,surs,dest;
int c[N][N],f[N][N];
int t[N],d[N];
int nh,h[N];
int inheap[N];
ll rez;
list< pair<int,int> > a[N];
inline int left_son(int x)
{
	return x<<1;
}
inline int right_son(int x)
{
	return (x<<1)+1;
}
inline int father(int x)
{
	return x>>1;
}
void upheap(int k)
{
	int key=h[k];
	while(k>1 && d[key]<d[h[father(k)]])
	{
		h[k]=h[father(k)];
		inheap[h[k]]=k;
		k=father(k);
	}
	h[k]=key;
	inheap[h[k]]=k;
}
void downheap(int k)
{
	int son=0;
	do
	{
		son=0;
		if(left_son(k)<=nh)
		{
			son=left_son(k);
			if(right_son(k)<=n && d[h[right_son(k)]]<d[h[son]])
				son=right_son(k);
			if(d[h[son]]>=d[h[k]])
				son=0;
		}
		if(son)
		{
			swap(h[k],h[son]);
			inheap[h[k]]=k;
			inheap[h[son]]=son;
			k=son;
		}
	}while(son);
}
inline void memset(int *v,int cine,int cat)
{
	for(int i=0; i<cat; ++i)
		v[i]=cine;
}
inline void citire()
{
	scanf("%d%d%d%d",&n,&m,&surs,&dest);
	int x,y,w,z;
	for(; m ; --m)
	{
		scanf("%d%d%d%d",&x,&y,&w,&z);
		a[x].pb(mp(y,z));
		a[y].pb(mp(x,-z));
		c[x][y]=w;
	}
}
inline void bellman_ford()
{
	vector<bool> incoada(N,false);
	queue<int> q;
	int now,next;
	memset(d,inf,N);
	q.push(surs);
	incoada[surs]=true;
	d[surs]=0;
	while(!q.empty())
	{
		now=q.front();
		q.pop();
		incoada[now]=false;
		for(list< pair<int,int> >::iterator it=a[now].begin(); it!=a[now].end(); ++it)
		{
			next=(*it).fs;
			if(d[next]>d[now]+(*it).sc && c[now][next]>f[now][next])
			{
				d[next]=d[now]+(*it).sc;
				if(!incoada[next])
				{
					q.push(next);
					incoada[next]=true;
				}
			}
		}
	}
	rez=d[dest];
}
bool dijkstra()
{
	int x;
	for(int i=1; i<=n; ++i)
	{
		for(list< pair<int,int> >::iterator it=a[i].begin(); it!=a[i].end(); ++it)
		{
			x=(*it).fs;
			if(d[i]!=inf && d[x]!=inf)
				(*it).sc=(*it).sc+d[i]-d[x];
		}
	}
	for(int i=0; i<=n; ++i)
	{
		d[i]=inf;
		inheap[i]=0;
		t[i]=-1;
	}
	nh=0;
	h[++nh]=surs;
	d[surs]=0;
	inheap[surs]=1;
	int now,next,cost;
	while(nh)
	{
		now=h[1];
		inheap[now]=0;
		h[1]=h[nh--];
		downheap(1);
		inheap[h[1]]=1;
		for(list< pair<int,int> >::iterator it=a[now].begin(); it!=a[now].end(); ++it)
		{
			next=(*it).fs;
			cost=(*it).sc;
			if(c[now][next]==f[now][next] || d[next]<=d[now]+cost)
				continue;
			d[next]=d[now]+cost;
			t[next]=now;
			if(inheap[next])
				upheap(inheap[next]);
			else
			{
				h[++nh]=next;
				inheap[h[nh]]=nh;
				upheap(nh);
			}
		}
	}
	if(d[dest]==inf)
		return false;
	rez+=d[dest];
	return true;
}
inline void flux()
{
	int i,r;
	ll sol=0;
	while(dijkstra())
	{
		i=dest;
		r=inf;
		while(i!=surs)
		{
			r=min(c[t[i]][i]-f[t[i]][i],r);
			i=t[i];
		}
		i=dest;
		while(i!=surs)
		{
			f[t[i]][i]+=r;
			f[i][t[i]]-=r;
			i=t[i];
		}
		sol+=(ll)r*rez;
	}
	printf("%lld\n",sol);
}
int main()
{
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	citire();
	bellman_ford();
	flux();
	return 0;
}