Cod sursa(job #3041616)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 31 martie 2023 20:24:48
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.6 kb
#include<fstream>
#include<vector>
#include<queue>
using namespace std;

ifstream cin("fmcm.in");
ofstream cout("fmcm.out");

class MCMF
{
    private: struct muchie{int from,to,cap,flow,cost;};
    const int INF = 1 << 28;
    vector<int> dist,p,pi,real; int s,t;
    vector<muchie> muchii; vector<vector<int>> vecini;

    void bf()
    {
        vector<bool> inq(dist.size()); queue<int> q;
        fill(pi.begin(),pi.end(),INF); q.push(s); dist[s] = 0;
        while(!q.empty())
            {
                int v = q.front(); q.pop(); inq[v] = 0;
                for(auto it : vecini[v])
                    {
                        muchie &h = muchii[it];
                        if((h.cap))
                            {
                                if(dist[h.to] > dist[v] + h.cost)
                                    {
                                        dist[h.to] = dist[v] + h.cost;
                                        if(!inq[h.to])
                                            {
                                                q.push(h.to);
                                                inq[h.to] = 1;
                                            }
                                    }
                            }
                    }
            }
    }

    bool dijkstra()
    {
        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;
        fill(dist.begin(),dist.end(),INF); fill(real.begin(),real.end(),0); fill(p.begin(),p.end(),-1);
        dist[s] = 0; pq.push({s,0}); while(!pq.empty())
        {
            int v = pq.top().first,co = pq.top().second; pq.pop();
            if(co != dist[v]) continue;
            for(auto it : vecini[v])
                {
                    if(muchii[it].cap - muchii[it].flow > 0)
                        {
                            int adaos = -pi[muchii[it].to] + pi[v] + muchii[it].cost;
                            if(dist[v] + adaos < dist[muchii[it].to])
                                {
                                    dist[muchii[it].to] = dist[v] + adaos;
                                    real[muchii[it].to] = real[v] + muchii[it].cost;
                                    p[muchii[it].to] = it; pq.push({muchii[it].to,dist[muchii[it].to]});
                                }
                        }
                }
        }

        return (p[t] != -1);


    }

    public:

    MCMF(int n,int _s,int _t)
    {
        vecini.resize(n + 1); dist.resize(n + 1); p.resize(n + 1);
        pi.resize(n + 1); real.resize(n + 1); s = _s; t = _t;
    }

    void add(int a,int b,int c,int d)
    {
        muchii.push_back({a,b,c,0,d});  vecini[a].emplace_back(muchii.size() - 1);
        muchii.push_back({b,a,0,0,-d}); vecini[b].emplace_back(muchii.size() - 1);
    }

    pair<int,int> vreau()
    {
        int mf = 0,mc = 0;
        bf(); while(dijkstra())
        {
            int delta = INF;
            for(int i = p[t] ; i != -1 ; i = p[muchii[i].from]) delta = min(delta,muchii[i].cap - muchii[i].flow);
            for(int i = p[t]; i != -1 ; i = p[muchii[i].from])
                {
                    muchii[i].flow     += delta;
                    muchii[i ^ 1].flow -= delta;
                }

            mc += delta * real[t];
            pi = real; mf += delta;
        }

        return {mf,mc};
    }
};

int main()
{
    int n,m,a,b,c,d,s,t; cin >> n >> m >> s >> t;
    MCMF graph(n,s,t); while(m--)
    {
        cin >> a >> b >> c >> d;
        graph.add(a,b,c,d);
    }

    cout << graph.vreau().second;
}