Cod sursa(job #2735190)

Utilizator Chirac_MateiChiriac Matei Chirac_Matei Data 1 aprilie 2021 22:47:08
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.93 kb
#include <bits/stdc++.h>
#pragma GCC optimize ("unroll-loops")

using namespace std;

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

struct pos
{
    int p;
    long long len;

    pos(int p, long long len)
    {
        this->p=p;
        this->len=len;
    }
    bool operator<(pos b) const
    {
        return len<b.len;
    }
};

int n,m,s,t;
vector<int> v[355];

int par[355];
long long flow[355][355];
long long cap[355][355];
long long cst[355][355];

vector<bool> inQ, viz;
vector<long long> realDist, newRealDist, positiveDist;

void bellman_ford()
{
    inQ.assign(n+1, false);
    realDist.assign(n+1, 1e18);

    queue<int> q;
    q.push(s);
    inQ[s]=true;
    realDist[s]=0;

    while(!q.empty())
    {
        int p=q.front();
        q.pop();

        inQ[p]=false;

        for(int it : v[p])
        {
            if(realDist[p]+cst[p][it] < realDist[it] && flow[p][it]<cap[p][it])
            {
                realDist[it]=realDist[p]+cst[p][it];
                if(!inQ[it])
                {
                    q.push(it);
                    inQ[it]=true;
                }
            }
        }
    }
}
void djikstra()
{
    positiveDist.assign(n+1, 1e18);
    newRealDist.assign(n+1, 1e18);
    viz.assign(n+1, false);

    multiset<pos> pq;
    pq.insert(pos(s, 0));

    positiveDist[s] = newRealDist[s] = 0;

    while(!pq.empty())
    {
        int p=pq.begin()->p;
        long long len=pq.begin()->len;
        pq.erase(pq.begin());

        if(viz[p])
            continue;

        viz[p]=true;

        for(int it : v[p])
        {
            long long positiveCost = realDist[p] + cst[p][it] - realDist[it];

            if(!viz[it] && positiveDist[p] + positiveCost < positiveDist[it] && flow[p][it] < cap[p][it])
            {
                positiveDist[it] = positiveDist[p] + positiveCost;
                pq.insert(pos(it, positiveDist[it]));

                newRealDist[it] = newRealDist[p] + cst[p][it];
                par[it]=p;
            }
        }
    }

    realDist = newRealDist;
}
long long mcmf()
{
    bellman_ford();

    long long ans=0;
    while(true)
    {
        djikstra();

        if(positiveDist[t] == 1e18)
            break;

        long long pushed=1e18;
        for(int p=t; p!=s; p=par[p])
            pushed=min(pushed, cap[par[p]][p] - flow[par[p]][p]);

        ans+=realDist[t]*pushed;
        for(int p=t; p!=s; p=par[p])
        {
            flow[par[p]][p]+=pushed;
            flow[p][par[p]]-=pushed;
        }
    }

    return ans;
}
int main()
{
    fin>>n>>m>>s>>t;

    while(m)
    {
        m--;
        int x,y;
        long long c, price;
        fin>>x>>y>>c>>price;

        v[x].push_back(y);
        v[y].push_back(x);

        cap[x][y]=c;

        cst[x][y]=price;
        cst[y][x]=-price;
    }

    fout<<mcmf();
    return 0;
}