Cod sursa(job #2962488)

Utilizator PatrascuAdrian1Patrascu Adrian Octavian PatrascuAdrian1 Data 8 ianuarie 2023 17:40:56
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.45 kb
#include <bits/stdc++.h>

using namespace std;

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

const int Nmax = 355;
vector<int> G[Nmax];
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> Q;
int Capac[Nmax][Nmax], dist[Nmax][Nmax];
int dp[Nmax], dpBF[Nmax], T[Nmax], realDist[Nmax];
bool seen[Nmax];
int N, M, S, D, flow;

void BellFord()
{
    queue<int> Q;
    memset(dpBF, 0x3f, sizeof(dpBF));
    dpBF[S] = 0;
    for(Q.push(S), seen[S] = 1; !Q.empty(); Q.pop())
    {
        int nod = Q.front();
        seen[nod] = 0;
        for(auto i : G[nod])
            if(Capac[nod][i])
            {
                if(dpBF[nod] + dist[nod][i] >= dpBF[i])
                    continue;

                dpBF[i] = dpBF[nod] + dist[nod][i];

                if(seen[i])
                    continue;

                seen[i] = 1;
                Q.push(i);
            }
    }
}

bool Dijkstra()
{
    for(int i = 1; i <= N; ++i)
        dp[i] = (1 << 30);
    memset(T, 0, sizeof(T));
    dp[S] = realDist[S] = 0;
    Q.push({0,S});
    T[S] = -1;
    while(!Q.empty())
    {
        int nod = Q.top().second;
        int cost = Q.top().first;
        Q.pop();
        if(dp[nod] != cost)
            continue;

        for(auto i : G[nod])
            if(Capac[nod][i])
            {
                int potentialDist = cost + dist[nod][i] + dpBF[nod] - dpBF[i];
                if(potentialDist < dp[i])
                {
                    dp[i] = potentialDist;
                    T[i] = nod;
                    realDist[i] = realDist[nod] + dist[nod][i];
                    Q.push({dp[i],i});
                }
            }
    }
    memcpy(dpBF, realDist, sizeof(dp));

    if(dp[D] == (1 << 30))
        return false;

    int MinCap = INT_MAX;

    for(int v = D, u = T[v]; v != S; v = u, u = T[u])
        MinCap = min(MinCap, Capac[u][v]);

    flow += MinCap * dpBF[D];
    for(int v = D, u = T[v]; v != S; v = u, u = T[u])
    {
        Capac[u][v] -= MinCap;
        Capac[v][u] += MinCap;
    }
    return true;
}

int main()
{
    in >> N >> M >> S >> D;
    while(M--)
    {
        int x, y, cap, cost;
        in >> x >> y >> cap >> cost;
        G[x].push_back(y);
        G[y].push_back(x);
        Capac[x][y] = cap;
        dist[x][y] = cost;
        dist[y][x] = -cost;
    }
    BellFord();
    while(Dijkstra());
    out << flow;
    return 0;
}