Cod sursa(job #3031964)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 21 martie 2023 10:41:11
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.72 kb
#include <fstream>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
#include <functional>
#include <cassert>
using namespace std;
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
class FLUX
{
    int n;
    struct edge
    {
        int x,y,flux,cap,cost;
    };
    vector<edge>e;
    vector<vector<int>>a;
    vector<int>t,dist;
    bool ford(int s,int d)
    {
        fill(t.begin(),t.end(),-1);
        fill(dist.begin(),dist.end(),2e9);
        dist[s]=0;
        queue<pair<int,int>>q;
        q.push({s,0});
        while(q.size())
        {
            auto acm=q.front();
            q.pop();
            if(acm.second!=dist[acm.first])
            {
                continue;
            }
            int then=acm.first;
            for(const auto ind:a[then])
            {
                if(e[ind].flux==e[ind].cap)continue;
                if(dist[then]+e[ind].cost<dist[e[ind].y])
                {
                    dist[e[ind].y]=dist[then]+e[ind].cost;
                    t[e[ind].y]=ind;
                    if(e[ind].y!=d)q.push({e[ind].y,dist[e[ind].y]});
                }
            }
        }
        return (dist[d]!=2e9);
    }
public:
    FLUX(int n)
    {
        a=vector<vector<int>>(n);
        t=dist=vector<int>(n);
        this->n=n;
    }
    void add_edge(int x,int y,int cap,int cost)
    {
        a[x].push_back((int)e.size());
        e.push_back({x,y,0,cap,cost});
        a[y].push_back((int)e.size());
        e.push_back({y,x,0,0,-cost});
    }
    pair<int,int> Flux(int s,int d)
    {
        int flux=0,sum=0;
        while(ford(s,d))
        {
            int aux=d;
            int minn=2e9;
            while(aux!=s)
            {
                int ind=t[aux];
                cout<<ind<<' ';
                minn=min(minn,e[ind].cap-e[ind].flux);
                aux=e[ind].x;
            }
            aux=d;
            while(aux!=s)
            {
                int ind=t[aux];
                e[ind].flux+=minn;
                e[(ind^1)].flux-=minn;
                aux=e[ind].x;
            }
            flux+=minn;
            sum+=minn*dist[d];
        }
        return make_pair(sum,flux);
    }
};
void solve()
{
    int n,m,s,d;
    cin>>n>>m>>s>>d;
    s--;
    d--;
    FLUX flux(n);
    while(m--)
    {
        int x,y,cap,cost;
        cin>>x>>y>>cap>>cost;
        flux.add_edge(--x,--y,cap,cost);
    }
    cout<<flux.Flux(s,d).first;
}
int32_t main()
{
    function<string(bool)>sol=[&](bool x)
    {
        if(x)return "YES";
        return "NO";
    };
    int _=1;
    //cin>>_;
    while(_--)
    {
        solve();
    }
}