Cod sursa(job #669558)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 27 ianuarie 2012 11:54:16
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 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,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);
	
}
bool Dijkstra() {
	int i,nod,vecin;
	
	for(i=1;i<=n;i++)
		dist[i]=INF;
	for(i=1;i<=n;i++)
		loc[i]=0;
	heap[1]=S;
	loc[S]=1;
	dist[S]=0;
	vf=1;
	
	while(vf) {
		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) {
				if(!loc[vecin]) {
					heap[++vf]=vecin;
					loc[vecin]=vf;
					dist[vecin]=dist[nod]+Cost[nod][i];
					tata[vecin]=nod;
					up(loc[vecin]);
					}
				else
				if(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();
	
	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;
			}
		
		maxflow+=flux*/*(*/dist[D]/*-k*1000)*/;
		
		}
	
	ofstream out("fmcm.out");
	out<<maxflow<<'\n';
	out.close();
	
	return 0;

}