Cod sursa(job #1201888)

Utilizator heracleRadu Muntean heracle Data 26 iunie 2014 13:08:40
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>

FILE* in=fopen("fmcm.in","r");
FILE* out=fopen("fmcm.out","w");
const int Q=351;

int nrnod,nrmuc,s,d;

struct matrice
{
	int cap,cost,p,flux;
} v[Q][Q];

struct muchie{
	int a,b;
} m[12501];

struct pair
{
	int val,add;
};

struct comp{
	bool operator()(const pair& x,const pair& y) const
	{
		return v[m[x.val].a][m[x.val].b].cost+x.add>v[m[y.val].a][m[y.val].b].cost+y.add;
	}
};



std::priority_queue<pair,std::vector<pair>,comp> h;

bool viz[Q];
int pred[Q];

pair mp(int a, int b)
{
	pair x;
	x.val=a;
	x.add=b;
	return x;
}

bool disjk()
{
	memset(viz,0,sizeof viz);
	int act=s;
	while(!h.empty())
		h.pop();
	viz[s]=1;
	for(int i=1; i<=nrnod; i++)
	{
		if(v[s][i].cap-v[s][i].flux>0)
		{
			h.push( mp(v[s][i].p,0) );
		}
	}
	
	pair tot;
	int par;

	while(!h.empty())
	{
		tot=h.top();
		par=tot.val;
		h.pop();
		if(viz[m[par].b]==1)
			continue;
		act=m[par].b;

		
		viz[act]=1;
		pred[act]=m[par].a;

		if(act==d)
		{
			return 1;		
		}


		for(int i=1; i<=nrnod; i++)
		{
			if(viz[i]==0 && v[act][i].cap-v[act][i].flux>0)
				h.push(mp(v[act][i].p,tot.add+v[m[par].a][act].cost));
		}
	}
	return 0;
}

int parcurge()
{
	int act=d;
	int rez=2000000000;
	while(pred[act]!=0)
	{
		if(v[pred[act]][act].cap-v[pred[act]][act].flux<rez)
			rez=v[pred[act]][act].cap-v[pred[act]][act].flux;
		act=pred[act];
	}
	return rez;
}

int cc;

void fluxeaza(int x)
{
	int act=d;

	while(pred[act]!=0)
	{
		if(v[pred[act]][act].flux>=0)
			cc+=v[pred[act]][act].cost*x;
		else
			cc-=v[pred[act]][act].flux*x;

		v[pred[act]][act].flux+=x;

		v[act][pred[act]].flux-=x;
		act=pred[act];
	}
}

int main()
{
	fscanf(in,"%d%d%d%d",&nrnod,&nrmuc,&s,&d);

	int a,b,cap,cost;

	for(int i=1; i<=nrmuc; i++)
	{
		fscanf(in,"%d%d%d%d",&a,&b,&cap,&cost);
		v[a][b].cap=cap;
		v[a][b].cost=cost;
		v[b][a].cost=-cost;
		v[a][b].p=i;
		m[i].a=a;
		m[i].b=b;
	}
	int min;
	while(disjk())
	{
		min=parcurge();
		fluxeaza(min);
	}
	fprintf(out,"%d",cc);
}