Cod sursa(job #2586546)

Utilizator CyborgSquirrelJardan Andrei CyborgSquirrel Data 21 martie 2020 09:37:16
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

const int INF = 0x3f3f3f3f;
struct nod{
	int a, v = INF;
	bool operator<(const nod &rhs)const{
		if(v != rhs.v){
			return v > rhs.v;
		}else{
			return a > rhs.a;
		}
	}
};

const int N = 410;

int n, m, s, d;
int cap[N][N];
int rcst[N][N];

vector<int> gra[N];

void read(){
	fin >> n >> m >> s >> d;
	for(int i = 0; i < m; ++i){
		int a, b;
		fin >> a >> b;
		fin >> cap[a][b] >> rcst[a][b];
		rcst[b][a] = -rcst[a][b];
		gra[a].push_back(b);
		gra[b].push_back(a);
	}
}

int dist[N], rdist[N], cdist[N];

void nuke(){
	for(int i = 1; i <= n; ++i){
		dist[i] = INF;
	}
}

void bellman(){
	static queue<int> qu;
	static bool vi[N];
	
	qu.push(s);
	cdist[s] = 0;
	vi[s] = true;
	while(!qu.empty()){
		int a = qu.front();
		qu.pop();
		vi[a] = false;
		for(auto b : gra[a]){
			int v = cdist[a]+rcst[a][b];
			if(v < cdist[b] && cap[a][b] != 0){
				cdist[b] = v;
				if(!vi[b]){
					qu.push(b);
					vi[b] = true;
				}
			}
		}
	}
}

int cst(int a, int b){
	return cdist[a] - cdist[b] + rcst[a][b];
}

priority_queue<nod> pq;
int dad[N];
bool dijkstra(){
	nuke();
	pq.push({s, 0});
	dist[s] = rdist[s] = 0;
	while(!pq.empty()){
		nod nd = pq.top();pq.pop();
		int a = nd.a;
		if(nd.v == dist[a]){
			for(auto b : gra[a]){
				int v = dist[a] + cst(a, b);
				if(v < dist[b] && cap[a][b] > 0){
					dad[b] = a;
					dist[b] = v;
					rdist[b] = rdist[a]+rcst[a][b];
					pq.push({b, dist[b]});
				}
			}
		}
	}
	for(int i = 1; i <= n; ++i){
		cdist[i] = rdist[i];
	}
	return dist[d] != INF;
}

int updateflow(){
	int fmin = INF;
	for(int x = d; x != s; x = dad[x]){
		fmin = min(fmin, cap[dad[x]][x]);
	}
	if(fmin != 0){
		for(int x = d; x != s; x = dad[x]){
			cap[dad[x]][x] -= fmin;
			cap[x][dad[x]] += fmin;
		}
		return fmin*rdist[d];
	}
	return 0;
}

int ans = 0;
void maxflow(){
	while(dijkstra()){
		ans += updateflow();
	}
}

void solve(){
	bellman();
	maxflow();
}

int main(){
	ios_base::sync_with_stdio(false);
	read();
	solve();
	fout << ans;
	return 0;
}