Cod sursa(job #3137025)

Utilizator proflaurianPanaete Adrian proflaurian Data 10 iunie 2023 11:39:34
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.22 kb
#include<bits/stdc++.h>
using namespace std;
const int M=25010;
const int N=351;
const int oo=2000000000;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int n,m,s,d,i,j,k,cp,cs,cap[N][N],flow[N][N],q[N],
    dad[N],P[N],price[N][N],PRICE,djikstra();
vector<int> v[N];
deque<int> Q;
void upd(),bellman();
int main()
{
    f>>n>>m>>s>>d;
    for(; m; m--)
    {
        int x,y,cp,cs;
        f>>x>>y>>cp>>cs;
        cap[x][y]=cp;
        price[x][y]=cs;
        price[y][x]=-cs;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    bellman();
    for(; djikstra();)upd();
    g<<PRICE;
    return 0;
}
void bellman()
{
    queue<int> Q;
    for(int i=1; i<=n; i++)
        P[i]=oo;
    P[s]=0;
    dad[s]=s;
    Q.push(s);
    q[s]=1;
    for(; Q.size();)
    {
        int nod=Q.front();
        Q.pop();
        q[nod]=0;
        for(auto vec:v[nod])
            if(cap[nod][vec]-flow[nod][vec]>0&&P[vec]>P[nod]+price[vec][nod])
            {
                if(!q[vec])
                {
                    q[vec]=1;
                    Q.push(vec);
                }
                dad[vec]=nod;
                P[vec]=P[nod]+price[nod][vec];
            }
    }
    cs=P[d];
}
int djikstra()
{
    bitset<N> viz;
    viz.reset();
    /// refac costurile pe reteaua reziduala
    for(int nod=1; nod<=n; nod++)
    {
        if(P[nod]==oo)continue;/// nu mai am drum spre nodul i
        /// in reteaua reziduala
        for(auto vec:v[nod])
        {
            if(P[vec]==oo)continue;/// nu mai am drum spre vecin in reteaua
            /// reziduala
            price[nod][vec]+=P[nod]-P[vec];
            /// refac costul nod i -> vecin sa am cost pozitiv
        }
    }
    /// djikstra cu noul graf
    priority_queue<pair<int,int>> pq;
    for(i=1; i<=n; i++)
    {
        P[i]=oo;
        dad[i]=i;
    }
    /// reinitializez costurile cu oo
    pq.push(make_pair(0,s));
    P[s]=0;viz[s]=1;
    /// pun in coada de prioritati djikstra sursa cu cost 0

    /// aplic djikstra
    ///P[s]=0;H[s]=PH[s]=1;H[1]=PH[1]=s;
    while(pq.size())
    {
        int nod,cost;
        tie(cost,nod)=pq.top();
        pq.pop();
        cost=-cost;
        if(viz[nod])
            continue;
        viz[nod]=1;
        ///in djikstra costurile se pun cu semn schimbat
        for(auto vec:v[nod])
            if(viz[vec]==0&&cap[nod][vec]>flow[nod][vec]&&P[vec]>P[nod]+price[nod][vec])
                {
                    P[vec]=P[nod]+price[nod][vec];
                    dad[vec]=nod;
                    pq.push(make_pair(-P[vec],vec));
                }
    }
    if(P[d]==oo)/// nu am ajuns la destinatie
        return 0;
    return 1;/// am ajuns la destinatie
}
void upd()
{
    cs+=P[d];
    /// costul real la destinatie =
    /// costul fals+costul la destinatie
    int flowNow=oo,x=dad[d],y=d;
    /// sursa este singurul nod pt care dad[x]=x
    while(x!=y)
    {
        flowNow=min(flowNow,cap[x][y]-flow[x][y]);
        x=dad[x];
        y=dad[y];
    }
    x=dad[d];
    y=d;
    while(x!=y)
    {
        flow[x][y]+=flowNow;
        flow[y][x]-=flowNow;
        x=dad[x];
        y=dad[y];
    }
    PRICE+=flowNow*cs;
}