Cod sursa(job #2292922)

Utilizator danielsociuSociu Daniel danielsociu Data 30 noiembrie 2018 11:28:20
Problema Flux maxim de cost minim Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.49 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#define maxn 310
#define pb push_back
#define inf 0x3f3f3f3f
#define minim(a,b) a>b?b:a

int n,m,S,D,cost[maxn][maxn],flux[maxn][maxn],SOL;
vector<int> g[maxn];

int old_d[maxn];
bool inqueue[maxn];
queue<int> belman;

int real_d[maxn],d[maxn],h[maxn*2],poz[maxn],k;
int father[maxn];

void bellman_ford();
bool dijkstra_wHeap();
void pushInHeap(int,int);
int popFromHeap(int);

int main()
{
	int x,y,f,c;
	fin>>n>>m>>S>>D;
	for(;m--;){
		fin>>x>>y>>f>>c;
		g[x].pb(y);
		g[y].pb(x);
		flux[x][y]=f;
		cost[x][y]=c;
		cost[y][x]=-cost[x][y];
	}
	bellman_ford();
	for(;dijkstra_wHeap(););
	fout<<SOL;
	return 0;
}

bool dijkstra_wHeap()
{
	int mini=inf;
	memset(d,inf,sizeof(d));
	d[S]=0;h[++k]=S;poz[S]=1;
	real_d[S]=0;

	while(k>0){
		int nod=popFromHeap(1);
		for(auto it=g[nod].begin();it!=g[nod].end();it++)
			if(flux[nod][*it])
				{
				int newval=d[nod]+cost[nod][*it]+old_d[nod]-old_d[*it];
				if(newval<=d[*it]){
					d[*it]=newval;
					father[*it]=nod;
					real_d[*it]=real_d[nod]+cost[nod][*it];
					if(poz[*it]==0){
						++k;
						pushInHeap(*it,k);
					}else
						pushInHeap(*it,poz[*it]);
				}
			}
	}
	for(int i=1;i<=n;i++)
		old_d[i]=real_d[i];
	if(d[D]==inf)
		return false;
	for(int i=D;i!=S;i=father[i])
		mini=minim(mini,flux[father[i]][i]);
	SOL+=(mini*real_d[D]);
	for(int i=D;i!=S;i=father[i])
		flux[father[i]][i]-=mini,
		flux[i][father[i]]+=mini;
	return true;

}

int popFromHeap(int pos)
{
	int ans=h[pos],x=pos,y=-1,aux;
	poz[h[pos]]=0;
	h[pos]=h[k--];
	poz[h[pos]]=pos;
	while(x!=y){
		y=x;
		if(d[h[x]]>d[h[x<<1]]&&(x<<1)<=k)
			x=(y<<1);
		if(d[h[x]]>d[h[(y<<1)+1]]&&((y<<1)+1)<=k)
			x=(y<<1)+1;
		aux=h[x],h[x]=h[y],h[y]=aux;
		poz[h[x]]=x,poz[h[y]]=y;
	}
	return ans;
}

void pushInHeap(int nod,int x)
{
	int aux,tata;
	poz[nod]=x;
	h[x]=nod;
	tata=x;

	while(x>1){
		tata=x>>1;
		if(d[h[tata]]>d[h[x]]){
			aux=h[tata];h[tata]=h[x];h[x]=aux;
			poz[h[tata]]=tata;poz[h[x]]=x;
			x=tata;
		}	else
			x=1;
	}
}

void bellman_ford()
{
		memset(old_d,inf,sizeof(old_d));
		old_d[S]=0;
		belman.push(S);
		inqueue[S]=1;
		while(!belman.empty()){
			int nod = belman.front();
			belman.pop();
			inqueue[nod]=false;
			for(auto it=g[nod].begin();it!=g[nod].end();it++)
				if(flux[nod][*it])
					if(old_d[*it]>old_d[nod]+cost[nod][*it]){
						old_d[*it]=old_d[nod]+cost[nod][*it];
						if(!inqueue[*it])
							inqueue[*it]=true,belman.push(*it);
					}

		}
}