Cod sursa(job #669766)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 27 ianuarie 2012 18:41:32
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.48 kb
#include <fstream>
#include <vector>
#define NMAx 356
#define INF (1<<28)
#define left(i) (2*i)
#define right(i) (2*i+1)
#define father(i) (i/2)
#define cmp(a,b) (dist[heap[a]]<dist[heap[b]])
using namespace std;
vector <short> G[NMAx],Cost[NMAx];
int n,S,D,maxflow,vf,sum,Flux[NMAx][NMAx],dist[NMAx];
int tata[NMAx],heap[NMAx],loc[NMAx];

void up(int nod) {
	
	while(nod>1&&cmp(nod,father(nod))) {
		swap(heap[nod],heap[father(nod)]);
		swap(loc[heap[nod]],loc[heap[father(nod)]]);
		nod=father(nod);
		}
	
}
void down(int nod) {
	
	int son;
	do {
		son=0;
		if(left(nod)<=vf) {
			son=left(nod);
			if(right(nod)<=vf&&cmp(right(nod),left(nod)))
				son=right(nod);
			if(cmp(nod,son))
				son=0;
			}
		if(son) {
			swap(heap[nod],heap[son]);
			swap(loc[heap[nod]],loc[heap[son]]);
			nod=son;
			}
	}while(son);
	
}
void BellmanFord() {
	
	int ok=1,i,j,nod;
	for(i=1;i<=n;i++)
		dist[i]=INF;
	dist[S]=0;
	
	for(j=1;j<=n&&ok;j++) {
		
		ok=0;
		for(nod=1;nod<=n;nod++)
			for(i=0;i<G[nod].size();i++)
				if(Flux[nod][G[nod][i]]>0&&dist[nod]+Cost[nod][i]<dist[G[nod][i]]) {
					dist[G[nod][i]]=dist[nod]+Cost[nod][i];
					ok=1;
					}
		}
	
	sum=dist[D];
}
bool Dijkstra() {
	int i,j,nod=S,vecin;
	
	for(i=1;i<=n;i++)
		for(j=0;j<G[i].size();j++)
			if(dist[i]!=INF&&dist[G[i][j]]!=INF)
				Cost[i][j]+=dist[i]-dist[G[i][j]];

	for(i=1;i<=n;i++) {
		heap[i]=i;
		loc[i]=i;
		dist[i]=INF;
		}
	heap[1]=S;
	heap[S]=1;
	loc[S]=1;
	loc[1]=S;
	dist[S]=0;
	vf=n;
	
	while(vf&&dist[nod]!=INF) {
		nod=heap[1];
		heap[1]=heap[vf--];
		loc[heap[1]]=1;
		down(1);
		for(i=0;i<G[nod].size();i++) {
			vecin=G[nod][i];
			if(Flux[nod][vecin]>0&&dist[vecin]>dist[nod]+Cost[nod][i]) {
				dist[vecin]=dist[nod]+Cost[nod][i];
				tata[vecin]=nod;
				up(loc[vecin]);
				}
			}
		}
	
	if(dist[D]==INF)
		return 0;
	return 1;
	
}
void citire() {
	
	int i,x,y,cap,cost,m;
	ifstream in("fmcm.in");
	in>>n>>m>>S>>D;
	for(i=0;i<m;i++) {
		in>>x>>y>>cap>>cost;
		//cost+=1000;
		G[x].push_back(y);
		G[y].push_back(x);
		Flux[x][y]=cap;
		Cost[x].push_back(cost);
		Cost[y].push_back(-cost);
		}
	in.close();

}
int main() {
	
	int nod,flux,k;
	citire();
	BellmanFord();
	
	while(Dijkstra()) {
		
		flux=INF;
		k=0;
		for(nod=D;nod!=S;nod=tata[nod],k++)
			flux=min(flux,Flux[tata[nod]][nod]);
		
		for(nod=D;nod!=S;nod=tata[nod]) {
			Flux[tata[nod]][nod]-=flux;
			Flux[nod][tata[nod]]+=flux;
			}
		
		sum+=dist[D];
		maxflow+=flux*sum;
		}
	
	ofstream out("fmcm.out");
	out<<maxflow<<'\n';
	out.close();
	
	return 0;

}