Cod sursa(job #2585827)

Utilizator CyborgSquirrelJardan Andrei CyborgSquirrel Data 19 martie 2020 14:18:17
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.79 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

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

typedef long long lint;

const int INF = 0x3f3f3f3f;

int n, m, s, d;
int cap[410][410], flo[410][410], cst[410][410];

vector<int> gra[410];

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

queue<int> qu;
bitset<410> vi;
int dad[410];
bool bfs(){
	vi.reset();
	qu.push(s);
	vi[s] = true;
	while(!qu.empty()){
		int a = qu.front();
		qu.pop();
		for(auto b : gra[a]){
			if(!vi[b] && flo[a][b] < cap[a][b]){
				vi[b] = true;
				if(b != d)qu.push(b);
			}
		}
	}
	return vi[d];
}

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

bool bvi[410];
void bellnuke(){
	for(int i = 1; i <= n; ++i){
		dist[i] = INF;
	}
	qu.push(s);
	bvi[s] = true;
	dist[s] = 0;
}

void bellman(){
	bellnuke();
	while(!qu.empty()){
		int a = qu.front();
		qu.pop();
		bvi[a] = false;
		for(auto b : gra[a]){
			int v = dist[a]+cst[a][b];
			if(v < dist[b] && flo[a][b] < cap[a][b]){
				dist[b] = v;
				dad[b] = a;
				if(!bvi[b]){
					qu.push(b);
					bvi[b] = true;
				}
			}
		}
	}
}

lint ans = 0;
void maxflow(){
	while(bfs()){
		bellman();
		ans += updateflow();
	}
}

void solve(){
	maxflow();
}

int main(){
	read();
	solve();
	fout << ans;
	return 0;
}