Cod sursa(job #2403908)

Utilizator MaarcellKurt Godel Maarcell Data 12 aprilie 2019 01:12:18
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.8 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <ctime>
#include <unordered_map>
#include <iomanip>
#include <complex>
#include <cassert>
using namespace std;

#define fi first
#define se second
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define deb(a) cerr<< #a << "= " << (a)<<"\n";

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef long double ld;
typedef complex<double> base;
typedef vector<int> vi;
typedef pair<int,int> pii;

template<class T> ostream& operator<<(ostream& stream, const vector<T> v){ stream << "[ "; for (int i=0; i<(int)v.size(); i++) stream << v[i] << " "; stream << "]"; return stream; }
ll fpow(ll x, ll p, ll m){ll r=1; for (;p;p>>=1){ if (p&1) r=r*x%m; x=x*x%m; } return r;}
ll inv(ll a, ll b){ return a<2 ? a : ((a-inv(b%a,a))*b+1)/a%b; }
int gcd(int a, int b){ if (!b) return a; return gcd(b,a%b);}
ll gcd(ll a, ll b){ if (!b) return a; return gcd(b,a%b);}



int N,M,S,D,p[400],f[400][400],cap[400][400],cost[400][400],dist[400],from[400];
vi g[400];

void bellman(){
	memset(p,-1,sizeof(p));
	p[S] = 0;
	
	vi q = {S};
	
	while (!q.empty()){
		vi nq;
		
		for (int cr : q){
			for (int nxt : g[cr])
				if (cap[cr][nxt] && (p[nxt]==-1 || p[cr]+cost[cr][nxt]<p[nxt])){
					p[nxt] =  p[cr]+cost[cr][nxt];
					nq.pb(nxt);
				}
		}
		
		q = nq;
	}
}

pii dijkstra(){
	set<pii> st;
	memset(dist,-1,sizeof(dist));
	
	dist[S]=0;
	st.insert({0,S});
	
	while (!st.empty()){
		auto cr = *(st.begin());
		st.erase(st.begin());
		
		int nod = cr.se;
		
		for (int nxt : g[nod]){
			int new_dist = dist[nod]+cost[nod][nxt]+p[nod]-p[nxt];;
			if (f[nod][nxt]<cap[nod][nxt] && (dist[nxt]==-1 || new_dist<dist[nxt])){
				if (dist[nxt]!=-1){
					st.erase({dist[nxt],nxt});
				}
				
				dist[nxt] = new_dist;
				from[nxt] = nod;
				st.insert({dist[nxt],nxt});
			}
		}
	}
	
	if (dist[D]==-1) return {0,0};
	
	int cr=D,cmin=(1<<30);
	while (cr!=S){
		int prev=from[cr];
		cmin=min(cmin,cap[prev][cr]-f[prev][cr]);
		cr = prev;
	}
	
	int tot_cost = cmin*(dist[D]+p[D]);
	
	cr = D;
	while (cr!=S){
		int prev=from[cr];
		f[prev][cr]+=cmin;
		f[cr][prev]-=cmin;
		cr = prev;
	}
	
	for (int i=1; i<=N; i++)
		p[i]=dist[i]+p[i];
		
	return {cmin,tot_cost};
}

int fmcm(){
	bellman();
	
	pii flow = dijkstra();
	int res = 0;
	
	while (flow.fi){
		//cout << flow.fi << " " << flow.se << "\n";
		res+=flow.se,flow=dijkstra();
	}
		
	return res;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	ifstream cin("fmcm.in");
	ofstream cout("fmcm.out");
	cin >> N >> M >> S >> D;
	
	for (int i=1; i<=M; i++){
		int x,y,c,cst;
		cin >> x >> y >> c >> cst;
		cap[x][y] = c;
		cost[x][y] = cst;
		cost[y][x] = -cst;
		
		g[x].pb(y);
		g[y].pb(x);
	}
	
	
	cout << fmcm() << "\n";
}