Cod sursa(job #2151211)

Utilizator MaarcellKurt Godel Maarcell Data 4 martie 2018 11:25:29
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.58 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 L,R,N,M,S,D,d[700],F[700][700],C[700][700],P[700][700],p[700]; vi g[700];
pii h[13000]; int T,pos[700];

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

void add(pii v){
	h[++T]=v;
	pos[v.se]=T;
	
	int p=T;
	
	while (p>1 && h[p]<h[p/2]){
		swap(pos[h[p].se],pos[h[p/2].se]);
		swap(h[p],h[p/2]);
		p/=2;
	}
	
}

void rmv(int nod){
	int p=pos[nod];
	
	h[p]=h[T--];
	pos[h[p].se]=p;

	while (p>1 && h[p]<h[p/2]){
		swap(pos[h[p].se],pos[h[p/2].se]);
		swap(h[p],h[p/2]);
		p/=2;
	}
	
	while (2*p<=T){
		int x=2*p;
		if (x<T && h[x]>h[x+1]) x++;
		
		if (h[x]<h[p]){
			swap(pos[h[x].se],pos[h[p].se]);
			swap(h[x],h[p]);
			
			p=x;
		}
		else break;
	}
	
}

pii dijkstra(){
	int i;
	set<pii> st;
	vi f(N);
	
	for (i=0; i<N; i++)
		d[i]=-1;
	
	d[S]=0;
	
	
	add({0,S});
	 
	while (T>0){
		
		pii cr=h[1];
		rmv(cr.se);
		
		int nod=cr.se;
		
		for (int nxt : g[nod])
			if (C[nod][nxt]-F[nod][nxt]>0){
				int cst=P[nod][nxt]+p[nod]-p[nxt];
				
				if (d[nxt]==-1 || d[nod]+cst<d[nxt]){
					if (d[nxt]!=-1) rmv(nxt);
					d[nxt]=cst+d[nod];
					f[nxt]=nod;
					add({d[nxt],nxt});
				}
			}
		
	}
	
	
	if (d[D]==-1) return {0,0};
	for (i=0; i<N; i++)
		p[i]=d[i]+p[i];
	
	
	
	
	int fl=(1<<30),cr;
	for (cr=D; cr!=S; cr=f[cr])
		fl=min(fl,C[f[cr]][cr]-F[f[cr]][cr]);
		
	for (cr=D; cr!=S; cr=f[cr]){
		F[f[cr]][cr]+=fl;
		F[cr][f[cr]]-=fl;
	}
	;
	return {fl,fl*p[D]};
	
}

void bellman_ford(){
	
    int i;
    for (i=0; i<N; i++)
        d[i]=(1<<30);
     
    vi q,nq,ind(N);
    q.pb(S);
   
    d[S]=0;
	
    for (i=1; i<=N && !q.empty(); i++){
        nq.clear();
        for (int x : q){
             
            for (int y : g[x]){
                 
                if (C[x][y]-F[x][y]>0 && (d[y]>P[x][y]+d[x])){
                    d[y]=P[x][y]+d[x];
                    if (ind[y]!=i) nq.pb(y);
                    ind[y]=i;
                }
            }
        }
         
         
        q=nq;
    }
     
	for (i=0; i<N; i++)
		p[i]=d[i];
}
 
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    cin >> N >> M >> S >> D;
    S--,D--;
   
    int i;
    
    for (i=1; i<=M; i++){
        int x,y,c,z;
        cin >> x >> y >> c >> z;
        x--,y--;
        add_edge(x,y,c,z);
    }
    
     
    int f=0,c=0;
    bellman_ford();
    
    while (1){
         
        pii r=dijkstra();
        if (r.fi==0) break;
         
        f+=r.fi,c+=r.se;
    }
     
    cout << c;
    return 0;
}