Cod sursa(job #300534)

Utilizator swift90Ionut Bogdanescu swift90 Data 7 aprilie 2009 14:59:45
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define fs first
#define sc second
#define INF 1000000000
typedef pair<int, int> hh;
vector <hh> nr[355];
int n,m,S,D;
int cap[355][355],flux[355][355];
int dist[355],rez,tata[355];
int H,heap[355],inH[355];
void bellman_ford(){
	vector<bool> inQ(355,false);
	queue <int> Q;
	int x,y,i,ss;
	for(i=0;i<=n;++i)
		dist[i]=INF;
	Q.push(S);
	inQ[S]=true;
	dist[S]=0;
	while(!Q.empty()){
		x=Q.front();
		Q.pop();
		inQ[x]=false;
		ss=nr[x].size();
		for(i=0;i<ss;++i){
			y=nr[x][i].fs;
			if(dist[y]>dist[x]+nr[x][i].sc && cap[x][y]>flux[x][y]){
				dist[y]=dist[x]+nr[x][i].sc;
				if(!inQ[y]){
					Q.push(y);
					inQ[y]=true;
				}
			}
		}
	}
	rez=dist[D];
}
void upheap(int poz){
	int xx=heap[poz];
	while(poz>1 && dist[xx]<dist[heap[poz/2]]){
		heap[poz]=heap[poz/2];
		inH[heap[poz]]=poz;
		poz=poz/2;
	}
	heap[poz]=xx;
	inH[xx]=poz;
}
void downheap(int poz){
	int aux=poz;
	if(2*poz<=H && dist[heap[aux]]>dist[heap[2*poz]])
		aux=2*poz;
	if(2*poz+1<=H && dist[heap[aux]]>dist[heap[2*poz+1]])
		aux=2*poz+1;
	if(aux!=poz){
		swap(heap[aux],heap[poz]);
		inH[heap[aux]]=aux;
		inH[heap[poz]]=poz;
		downheap(aux);
	}
}
bool dijkstra(){
	int i,x,y,cc;
	for(i=1;i<=n;++i){
		for(vector<hh>::iterator it=nr[i].begin();it!=nr[i].end();++it){
			x=it->fs;
			if(dist[x]!=INF && dist[i]!=INF)
				it->sc=it->sc+dist[i]-dist[x];
		}
	}
	for(i=0;i<=n;++i){
		inH[i]=0;
		dist[i]=INF;
		tata[i]=-1;
	}
	H=0;
	heap[++H]=S;
	dist[S]=0;
	inH[S]=1;
	while(H){
		x=heap[1];
		inH[x]=0;
		heap[1]=heap[H--];
		downheap(1);
		inH[heap[1]]=1;
		for(vector<hh>::iterator it=nr[x].begin();it!=nr[x].end();++it){
			y=it->fs;
			cc=it->sc;
			if(cap[x][y]==flux[x][y] || dist[y]<=dist[x]+cc)
				continue;
			dist[y]=dist[x]+cc;
			tata[y]=x;
			if(inH[y])
				upheap(inH[y]);
			else{
				heap[++H]=y;
				inH[y]=H;
				upheap(H);
			}
		}
	}
	if(dist[D]==INF)
		return false;
	rez+=dist[D];
	return true;
}
void fflux(){
	int x,r;
	long long sol=0;
	while(dijkstra()){
		x=D;
		r=INF;
		while(x!=S){
			r=min(r,cap[tata[x]][x]-flux[tata[x]][x]);
			x=tata[x];
		}
		x=D;
		while(x!=S){
			flux[tata[x]][x]+=r;
			flux[x][tata[x]]-=r;
			x=tata[x];
		}
		sol=sol+(long long)r*rez;
	}
	printf("%lld\n",sol);
}
int main(){
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	int i,x,y,c,z;
	scanf("%d%d%d%d",&n,&m,&S,&D);
	for(i=0;i<m;++i){
		scanf("%d%d%d%d",&x,&y,&c,&z);
		nr[x].push_back(hh(y,z));
		nr[y].push_back(hh(x,-z));
		cap[x][y]=c;
	}
	bellman_ford();
	fflux();
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}