Cod sursa(job #431189)

Utilizator GotenAmza Catalin Goten Data 31 martie 2010 19:11:09
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.31 kb
#include<fstream>
#include<vector>
#include<queue>
#define oo (1<<30)
#define nmax 360
using namespace std;
vector <int> v[nmax];
int c[nmax][nmax],f[nmax][nmax],d[nmax],hh[nmax],h[nmax],L,padre[nmax];
int n,S,D;
long long rez,sum;
void bf()
{
	queue <int> Q;
	vector <int> :: iterator fiu;
	int i,nod;
	for(i=1;i<=n;i++)
		d[i]=oo;
	d[S]=0;
	Q.push(S);
	while(!Q.empty())
	{
		nod=Q.front();
		Q.pop();
		for(fiu=v[nod].begin();fiu!=v[nod].end();fiu++)
			if(f[nod][*fiu]&&d[*fiu]>d[nod]+c[nod][*fiu])
			{
				Q.push(*fiu);
				d[*fiu]=d[nod]+c[nod][*fiu];
			}
	}
	sum+=d[D];
}
int root()
{
	int safe=h[1],son,ls,rs,aux,nod=1;
	hh[h[L]]=1;
	h[1]=h[L--];
	do
	{
		son=0;
		ls=(nod<<1);
		rs=1+ls;
		if(ls<=L)
		{
			son=ls;
			if(rs<=L&&d[h[rs]]<d[h[son]])
				son=rs;
			if(d[h[son]]>=d[h[nod]])
				son=0;
		}
		if(son)
		{
			hh[h[son]]=nod;
			hh[h[nod]]=son;
			aux=h[nod];
			h[nod]=h[son];
			h[son]=aux;
			nod=son;
		}
	}
	while(son);
	hh[safe]=0;
	return safe;
}
void percolate(int nod)
{
	int safe=h[nod];
	while(nod>1&&d[h[nod>>1]]>d[safe])
	{
		hh[h[nod>>1]]=nod;
		h[nod]=h[nod>>1];
		nod>>=1;
	}
	hh[safe]=nod;
	h[nod]=safe;
}
int dijkstra()
{
	int nod,i,add=oo;
	vector <int>:: iterator fiu;
	for(i=1;i<=n;i++)
		for(fiu=v[i].begin();fiu!=v[i].end();fiu++)
			if(d[i]!=oo&&d[*fiu]!=oo)
				c[i][*fiu]+=d[i]-d[*fiu];
	for(i=1;i<=n;i++)
	{
		d[i]=oo;
		hh[i]=h[i]=i;
	}
	d[S]=0;
	h[S]=hh[S]=1;
	h[1]=hh[1]=S;
	L=n;
	while(L)
	{
		nod=root();
		for(fiu=v[nod].begin();fiu!=v[nod].end();fiu++)
			if(f[nod][*fiu]&&hh[*fiu]&&d[*fiu]>d[nod]+c[nod][*fiu])
			{
				d[*fiu]=d[nod]+c[nod][*fiu];
				padre[*fiu]=nod;
				percolate(hh[*fiu]);
			}
	}
	if(d[D]!=oo)
	{
		i=D;
		while(i!=S)
		{
			if(f[padre[i]][i]<add)
				add=f[padre[i]][i];
			i=padre[i];
		}
		i=D;
		while(i!=S)
		{
			f[padre[i]][i]-=add;
			f[i][padre[i]]+=add;
			i=padre[i];
		}
		sum+=d[D];
		rez+=sum*add;
		return 1;
	}
	return 0;
}	
int main()
{
	int m,x,y,cost,cap;
	ifstream read("fmcm.in");
	ofstream write("fmcm.out");
	read>>n>>m>>S>>D;
	while(m--)
	{
		read>>x>>y>>cap>>cost;
		c[x][y]=cost;
		c[y][x]=-cost;
		f[x][y]=cap;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	bf();
	while(dijkstra());
	write<<rez;
	return 0;
}