Cod sursa(job #718817)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 21 martie 2012 09:45:32
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.32 kb
#include<stdio.h>
#include<vector>
#include<queue>

#define maxn 355
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define INF 0x3f3f3f3f

using namespace std;

FILE*f=fopen("fmcm.in","r");
FILE*g=fopen("fmcm.out","w");

int n,m,S,D,L;
int dist[maxn],inq[maxn],H[maxn],Poz[maxn];
int T[maxn],C[maxn][maxn],F[maxn][maxn];
vector< pii >G[maxn];
queue<int>Q;

inline void citire () {
	
	fscanf(f,"%d %d %d %d",&n,&m,&S,&D);
	
	int x,y,cap,cost;
	for ( int i = 1 ; i <= m ; ++i ){
		fscanf(f,"%d %d %d %d",&x,&y,&cap,&cost);
		
		G[x].pb(mp(y,cost));
		G[y].pb(mp(x,-cost));
		
		C[x][y] = cap;
	}
}

inline void bellman_ford () {
	int nod;
	
	Q.push(S); inq[S] = 1;
	memset(dist,INF,sizeof(dist));
	dist[S] = 0;
	
	while ( !Q.empty() ){
		nod = Q.front(); Q.pop(); inq[nod] = 0;
		
		for ( vector< pii >::iterator itt = G[nod].begin() ; itt != G[nod].end() ; ++itt ){
			int nodvcn = itt->first; int cost = itt->second;
			if ( dist[nodvcn] > dist[nod] + cost && C[nod][nodvcn] > F[nod][nodvcn] ){
				dist[nodvcn] = dist[nod] + cost;
				
				if ( !inq[nodvcn] ){
					Q.push(nodvcn); inq[nodvcn] = 1;
				}
			}
		}
	}
}

inline void update_costs () {
	
	for ( int i = 1 ; i <= n ; ++i ){
		for ( vector< pii >::iterator itt = G[i].begin() ; itt != G[i].end() ; ++itt ){
			int nodvcn = itt->first; int cost = itt->second;
			itt->second = cost + dist[i] - dist[nodvcn];
		}
	}
}

inline void swap ( int &a , int &b ){
	int aux = a ; a = b ; b = aux;
}

inline void urca ( int poz ){
	
	while ( poz > 1 && dist[H[poz>>1]] > dist[H[poz]] ){
		swap(H[poz>>1],H[poz]);
		swap(Poz[H[poz>>1]],Poz[H[poz]]);
		poz >>= 1;
	}
}

inline void coboara ( int x ){
	int y = 0;
	
	while ( x != y ){
		y = x;
		
		if ( 2*y <= L && dist[H[2*y]] < dist[H[x]] ){
			x = 2*y;
		}
		if ( 2*y+1 <= L && dist[H[2*y+1]] < dist[H[x]] ){
			x = 2*y+1;
		}
		
		swap(H[x],H[y]);
		swap(Poz[H[x]],Poz[H[y]]);
	}
}

inline void insert ( int nod ){
	
	H[++L] = nod; Poz[nod] = L;
	urca(L);
}

inline int pop () {
	int nod = H[1];
	
	swap(H[1],H[L]); swap(Poz[H[1]],Poz[H[L]]);
	H[L] = Poz[H[L]] = 0; --L;
	coboara(1);
	
	return nod;
}

inline bool dijkstra () {
	int nod;
	
	memset(dist,INF,sizeof(dist)); dist[S] = 0;
	insert(S);
	
	while ( L ){
		nod = pop();
		
		for ( vector< pii >::iterator itt = G[nod].begin() ; itt != G[nod].end() ; ++itt ){
			int nodvcn = itt->first; int cost = itt->second;
			
			if ( dist[nodvcn] > dist[nod] + cost && C[nod][nodvcn] > F[nod][nodvcn] ){
				dist[nodvcn] = dist[nod] + cost; T[nodvcn] = nod;
				
				if ( Poz[nodvcn] ){
					urca(Poz[nodvcn]);
				}
				else{
					insert(nodvcn);
				}
			}
		}
	}
	
	return dist[D] != INF;
}

inline void fmcm () {
	int cost = 0,lasttoD,minim,nod;
	
	bellman_ford(); lasttoD = dist[D];
	update_costs();
	
	while ( dijkstra() ){
		
		minim = INF;
		for ( nod = D ; T[nod] ; nod = T[nod] ){
			minim = min(minim,C[T[nod]][nod] - F[T[nod]][nod]);
		}
		for ( nod = D ; T[nod] ; nod = T[nod] ){
			F[T[nod]][nod] += minim;
			F[nod][T[nod]] -= minim;
		}
		
		cost += dist[D]*minim + lasttoD*minim; lasttoD += dist[D];
		update_costs();
	}
	
	fprintf(g,"%d\n",cost);
}

int main () {
	
	citire();
	fmcm();
	
	fclose(f);
	fclose(g);
	
	return 0;
}