Cod sursa(job #370998)

Utilizator victor.ionescuIonescu Victor Cristian victor.ionescu Data 2 decembrie 2009 23:04:36
Problema Flux maxim de cost minim Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
#include <fstream>
#include <vector>
#include <list>
#include <cstring>
#define MAX 400
#define INFINIT 2000000000
using namespace std;
ifstream fi("fmcm.in");
ofstream fo("fmcm.out");
int Dist[MAX],C[MAX][MAX],F[MAX][MAX],sursa,dest,poz[MAX],heap[MAX],T[MAX];
vector<pair<int,int> > G[MAX],Gi[MAX];
int DHeap,N,M;
list<int> Q;
int factor;


void citire(){
	fi>>N>>M>>sursa>>dest;
	int a,b,c,d;
	for (int i=1;i<=M;++i){
		fi>>a>>b>>c>>d;
		C[a][b]=c;
		G[a].push_back(make_pair(b,d));
		G[b].push_back(make_pair(a,-d));
		Gi[a].push_back(make_pair(b,d));
	}
}


void bellman(){
	for (int i=1;i<=N;++i) Dist[i]=INFINIT;
	Q.push_back(sursa);
	Dist[sursa]=0;
	while (!Q.empty()){
		list<int>::iterator it=Q.begin();
		for (unsigned int i=0;i<G[*it].size();++i) if (C[*it][G[*it][i].first]-F[*it][G[*it][i].first]>0)
			if ((Dist[*it]+G[*it][i].second)<Dist[G[*it][i].first]){
				Dist[G[*it][i].first]=Dist[*it]+G[*it][i].second;
				Q.push_back(G[*it][i].first);
			}
		Q.pop_front();
	}
	factor=Dist[dest];
}

void swap(int i,int j){
	int aux=heap[i];
	heap[i]=heap[j];
	heap[j]=aux;
	poz[heap[i]]=i;
	poz[heap[j]]=j;
}


void heap_up(int nod){
	int dad=nod/2;
	if (dad && Dist[heap[dad]]>Dist[heap[nod]]){
		swap(nod,dad);
		heap_up(dad);
	}
}

void heap_dw(int nod){
	int l=nod*2,r=l+1,minim=nod;
	if (l<=DHeap && Dist[heap[l]]<Dist[heap[minim]]) minim=l;
	if (r<=DHeap && Dist[heap[r]]<Dist[heap[minim]]) minim=r;
	if (minim!=nod){
		swap(nod,minim);
		heap_dw(minim);
	}
}

int dijkstra(){
	DHeap=N;

        for (int i=1;i<=N;++i)
                for (unsigned int j=0;j<G[i].size();++j)
                        if (Dist[i]!=INFINIT && Dist[G[i][j].first]!=INFINIT) G[i][j].second+=(Dist[i]-Dist[G[i][j].first]);
        
	for (int i=1;i<=N;++i){
		heap[i]=i;
		poz[i]=i;
		Dist[i]=INFINIT;
                T[i]=-1;
	}
	Dist[sursa]=0;
	heap_up(poz[sursa]);
        while (DHeap>1 && Dist[heap[1]]!=INFINIT){

                int nod=heap[1];
		for (unsigned int j=0;j<G[nod].size();++j) if (C[nod][G[nod][j].first]-F[nod][G[nod][j].first]>0) {
			if(Dist[G[nod][j].first]>(Dist[nod]+G[nod][j].second)){
				Dist[G[nod][j].first]=Dist[nod]+G[nod][j].second;
				T[G[nod][j].first]=nod;
			}
			heap_up(poz[G[nod][j].first]);
		}
                swap(1,DHeap);
                --DHeap;
                if (DHeap>1) heap_dw(1);

	}
	if (Dist[dest]!=INFINIT) return 1; else return 0;
}


void flow(){
	bellman();
	long long scost=0;
	for (;dijkstra();){
		int maxflow=INFINIT;
		for (int nod=dest;nod!=sursa;nod=T[nod])
                maxflow=min(maxflow,C[T[nod]][nod]-F[T[nod]][nod]);
		if (maxflow!=INFINIT && maxflow>0) {
			for (int nod=dest;nod!=sursa;nod=T[nod]) { F[T[nod]][nod]+=maxflow; F[nod][T[nod]]-=maxflow; }
			scost+=(long long)factor*maxflow;
		}
		factor+=Dist[dest];
	}
	fo<<scost<<"\n";
}

int main(){
	citire();
	flow();
	fi.close();fo.close();
	return 0;
}