Cod sursa(job #2965077)

Utilizator andu2006Alexandru Gheorghies andu2006 Data 14 ianuarie 2023 13:38:10
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include <bits/stdc++.h>
//#pragma GCC optimize("unroll-loops")

using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const ll NMAX=355,MMAX=12505,INF=1e9;
ll cap[NMAX][NMAX],cost[NMAX][NMAX];
vector<ll> edg[NMAX];
ll bellman_dist[NMAX],dist[NMAX],start,sink;
ll prv[NMAX];
set<pair<ll, ll > > s;
int main()
{
    ifstream fin("fmcm.in");
    ofstream fout("fmcm.out");
    ll n,m;
    fin>>n>>m>>start>>sink;
    for(ll i=1;i<=n;i++)
        for(ll j=1;j<=n;j++)
            cost[i][j]=INF;
    for(ll i=0;i<m;i++){
        ll u,v,c,z;
        fin>>u>>v>>c>>z;

        cost[u][v]=z,cost[v][u]=-z,cap[u][v]=c;
        edg[u].push_back(v);
        edg[v].push_back(u);
    }
    if(start==sink){
        fout<<0;
        return 0;
    }
    for(ll i=1;i<=n;i++) bellman_dist[i]=INF;
    bellman_dist[start]=0;
    for(ll iter=0;iter<n;iter++){
        for(ll i=1;i<=n;i++){
            for(auto it : edg[i]){
                if(cap[i][it])
                    bellman_dist[it]=min(bellman_dist[it],bellman_dist[i]+cost[i][it]);
            }
        }
    }
    //assert(0);
    for(ll i=1;i<=n;i++)
        for(ll j=1;j<=n;j++)
            cost[i][j]+=bellman_dist[i]-bellman_dist[j];
    ll ans=0,total_cost=0;
    while(1){
        for(ll i=1;i<=n+1;i++) dist[i]=INF,prv[i]=n+1;
        dist[start]=0,prv[start]=start;
        s.insert({dist[start],start});
        while(!s.empty()){
            ll u=s.begin()->second;
            s.erase(s.begin());
            for(auto it : edg[u]){
                if(cap[u][it] && dist[u]+cost[u][it]<dist[it]){
                    if(dist[it]!=INF) s.erase({dist[it],it});
                    dist[it]=dist[u]+cost[u][it];
                    s.insert({dist[it],it});
                    prv[it]=u;
                }
            }
        }
        if(prv[sink]==n+1) break;
        ll total_flow=INF,aux=sink;
        while(aux!=start && aux!=n+1){
            total_flow=min(total_flow,cap[prv[aux]][aux]);
            aux=prv[aux];
        }
        aux=sink;
        ans+=total_flow,total_cost+=(dist[sink]+bellman_dist[sink])*total_flow;
        while(aux!=start && aux!=n+1){
            cap[prv[aux]][aux]-=total_flow,cap[aux][prv[aux]]+=total_flow;
            aux=prv[aux];
        }
    }
    fout<<total_cost;
    return 0;
}