Cod sursa(job #2735197)

Utilizator Chirac_MateiChiriac Matei Chirac_Matei Data 1 aprilie 2021 23:02:54
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <bits/stdc++.h>

using namespace std;

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

struct pos
{
    int p;
    int len;

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

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

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

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

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

    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, 1e9);
    newRealDist.assign(n+1, 1e9);
    viz.assign(n+1, false);

    priority_queue<pos> pq;
    pq.push(pos(s, 0));

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

    while(!pq.empty())
    {
        int p=pq.top().p;
        int len=pq.top().len;
        pq.pop();

        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.push(pos(it, positiveDist[it]));

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

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

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

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

        int pushed=1e9;
        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;
        int 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;
}