Cod sursa(job #2704660)

Utilizator Chirac_MateiChiriac Matei Chirac_Matei Data 10 februarie 2021 22:15:44
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.79 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");

struct edge
{
    int x, y;
    long long flow, cap, cost;
    edge(int x, int y, long long cap, long long cost)
    {
        this->x=x;
        this->y=y;
        this->cap=cap;
        this->cost=cost;

        this->flow=0;
    }
};
struct mcmf
{
    const long long inf=1e18;

    vector<edge> e;
    vector<vector<int>> adj;

    vector<long long> d;
    vector<int> last;
    vector<bool> inq;
    queue<int> q;

    int n, m=0, s, t;

    mcmf(int n, int s, int t)
    {
        this->n=n;
        this->s=s;
        this->t=t;

        adj.resize(n+1);
        d.resize(n+1);
        last.resize(n+1);
        inq.resize(n+1);
    }

    void add_edge(int x, int y, long long cap, long long cost)
    {
        e.push_back(edge(x, y, cap, cost));
        adj[x].push_back(m);

        e.push_back(edge(y, x, 0, -cost));
        adj[y].push_back(m+1);

        m+=2;
    }

    void spfa()
    {
        while(!q.empty())
            q.pop();

        fill(d.begin(), d.end(), inf);
        fill(last.begin(), last.end(), -1);
        fill(inq.begin(), inq.end(), false);

        d[s]=0;
        inq[s]=true;
        q.push(s);

        while(!q.empty())
        {
            int p=q.front();
            q.pop();
            inq[p]=false;

            for(int it : adj[p])
            {
                if(e[it].flow < e[it].cap && d[p]+e[it].cost < d[e[it].y])
                {
                    d[e[it].y]=d[p]+e[it].cost;
                    last[e[it].y]=it;

                    if(!inq[e[it].y])
                    {
                        q.push(e[it].y);
                        inq[e[it].y]=true;
                    }
                }
            }
        }
    }

    long long flow()
    {
        long long flow=0, ans=0;

        while(true)
        {
            spfa();

            if(d[t]==inf)
                break;

            int p=t;
            long long nflow=inf;
            while(p!=s)
            {
                int id=last[p];
                nflow=min(nflow, e[id].cap-e[id].flow);
                p=e[id].x;
            }

            ans+=nflow*d[t];
            flow+=nflow;

            p=t;
            while(p!=s)
            {
                int id=last[p];

                e[id].flow+=nflow;
                e[id^1].flow-=nflow;

                p=e[id].x;
            }
        }

        return ans;
    }
};

int n,m,s,t,i,x,y,cap,cost;

int main()
{
    fin>>n>>m>>s>>t;
    mcmf g=mcmf(n, s, t);

    for(i=1;i<=m;i++)
    {
        fin>>x>>y>>cap>>cost;
        g.add_edge(x, y, cap, cost);
    }

    fout<<g.flow();
    return 0;
}