Cod sursa(job #2176215)

Utilizator MaarcellKurt Godel Maarcell Data 16 martie 2018 21:40:07
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.74 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,F[400][400],C[400][400],cst[400][400],p[400],d[400];
vi g[400];
int tflow=0,tcost=0;

void add_edge(int x, int y, int c, int cost){
	g[x].pb(y);
	g[y].pb(x);
	
	C[x][y]+=c;
	cst[x][y]=cost;
	cst[y][x]=-cost;
}

void bellman_ford(){
	vi q,nq;
	vi ind(N+1,0);
	
	q.pb(S);
	for (int i=1; i<=N; i++)
		p[i]=(1<<30);
	p[S]=0;
	
	for (int i=1; i<=N; i++){
		nq.clear();
		for (int nod : q)
			for (int nxt : g[nod])
				if (C[nod][nxt] && p[nod]+cst[nod][nxt]<p[nxt]){
					p[nxt]=p[nod]+cst[nod][nxt];
					if (ind[nxt]!=i) nq.pb(nxt);
					ind[nxt]=i;
				}
				
		q=nq;
	}
}

int dijkstra(){
	int i;
	set<pii> st;
	vi f(N+1,0);
	
	st.insert({0,S});
	f[S]=-1;
	d[S]=0;
	
	while (!st.empty()){
		pii cr=*st.begin();
		st.erase(st.begin());
		
		int nod=cr.se;
		for (int nxt : g[nod])
			if (C[nod][nxt]-F[nod][nxt]>0){
				int cost=cst[nod][nxt]+p[nod]-p[nxt];
				if (!f[nxt] || d[nod]+cost<d[nxt]){
					if (f[nxt]!=0) st.erase({d[nxt],nxt});
					
					d[nxt]=d[nod]+cost;
					f[nxt]=nod;
					st.insert({d[nxt],nxt});
				}
			}
	}
	
	if (!f[D])
		return 0;
		
	int cost=d[D]+p[D],cr=D,flow=(1<<30);
	
	for (cr=D; cr!=S; cr=f[cr])
		flow=min(flow,C[f[cr]][cr]-F[f[cr]][cr]);
	
	cout << flow << " " << cost << "\n";
	tflow+=flow;
	tcost+=cost*flow;
	
	for (cr=D; cr!=S; cr=f[cr]){
		F[f[cr]][cr]+=flow;
		F[cr][f[cr]]-=flow;
	}
	
	for (i=1; i<=N; i++)
		p[i]=d[i]+p[i];
		
	return flow;
}

void fmcm(){
	bellman_ford();
		
	while (dijkstra())
		;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	ifstream fin("fmcm.in");
	ofstream fout("fmcm.out");
	fin >> N >> M >> S >> D;
	
	int i;
	for (i=1; i<=M; i++){
		int x,y,c,z;
		fin >> x >> y >> c >> z;
		add_edge(x,y,c,z);
	}
	
	fmcm();
	fout << tcost << "\n";
	return 0;
}