Cod sursa(job #2695465)

Utilizator usureluflorianUsurelu Florian-Robert usureluflorian Data 13 ianuarie 2021 10:30:34
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 4e2 + 3;

vector <int> v[nmax];
queue <int> q;
priority_queue < pair <int, int> , vector < pair <int, int> > , greater < pair <int, int> > > h;

int n, s, d, ans, usd[nmax], new_dist[nmax], dist[nmax], ant[nmax];
int flux[nmax][nmax], cost[nmax][nmax], usu[nmax][nmax];

void Bellman_Ford()
{
    int i, nod;

    for(int i = 1; i <= n; ++i)
        dist[i] = INT_MAX / 2;

    dist[s] = 0;
    q.push(s);

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

        for(int i = 0; i < v[nod].size(); ++i)
        {
            int vecin = v[nod][i];
            if (flux[nod][vecin] < usu[nod][vecin] && dist[vecin] > dist[nod] + cost[nod][vecin])
            {
                dist[vecin] = dist[nod] + cost[nod][vecin];
                q.push(vecin);
            }
        }
    }
}

int Dijkstra()
{
    int nod, flusu = INT_MAX;

    for(int i = 1; i <= n; ++i)
    {
        usd[i] = INT_MAX / 2;
        ant[i] = -1;
    }

    new_dist[s] = 0;
    usd[s] = 0;
    h.push({0, s});
    while (!h.empty())
    {
        int nod = h.top().second;
        int dst = h.top().first;
        h.pop();

        if (dst <= usd[nod])
        {
            for(int i = 0; i < v[nod].size(); ++i)
            {
                int vecin = v[nod][i];
                int dist_intre = cost[nod][vecin] + dist[nod] - dist[vecin];
                if (flux[nod][vecin] < usu[nod][vecin] && usd[vecin] > usd[nod] + dist_intre)
                {
                    usd[vecin] = usd[nod] + dist_intre;
                    new_dist[vecin] = cost[nod][vecin] + new_dist[nod];
                    ant[vecin] = nod;
                    h.push({usd[vecin], vecin});
                }
            }
        }
    }

    if (usd[d] == INT_MAX / 2) return false;

    nod = d;
    while (ant[nod] != -1)
    {
        flusu = min(flusu, usu[ant[nod]][nod] - flux[ant[nod]][nod]);
        nod = ant[nod];
    }

    nod = d;
    while (ant[nod] != -1)
    {
        flux[ant[nod]][nod] += flusu;
        flux[nod][ant[nod]] -= flusu;
        nod = ant[nod];
    }

    ans += flusu * new_dist[d];

    for (int i = 1; i <= n; ++i)
        dist[i]=new_dist[i];

    return true;
}

int m, x, y, c, z;

int main()
{
    ios::sync_with_stdio(false);
    f.tie(0);
    f >> n >> m >> s >> d;
    for (int i = 1; i <= m; ++i)
    {
        f >> x >> y >> c >> z;
        v[x].push_back(y);
        v[y].push_back(x);
        usu[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;
    }

    Bellman_Ford();
    while (Dijkstra());
    g << ans;
    return 0;
}