Cod sursa(job #2271156)

Utilizator slym777Darii Dan slym777 Data 28 octombrie 2018 10:39:08
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.01 kb
#pragma GCC optimize ("O3")
#include <iostream>
#include <bits/stdc++.h>
#define Nmax 500
#define pb push_back
#define inf 2000000
#define ll long long

using namespace std;

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

vector <int> V[Nmax];
int C[Nmax][Nmax],GR[Nmax][Nmax];
int tata[Nmax], dist[Nmax], d[Nmax], real_d[Nmax];
bool in_coada[Nmax];
ll flux_max = 0;

bool Dijkstra(int n, int s, int D)
{
    set <pair <int,int>> Q;
    for (int i = 1; i<=n; i++)
    {
        d[i] = inf;
        tata[i] = 0;
    }
    d[s] = 0; tata[s] = s;
    real_d[s] = 0;
    Q.insert({0,s});
    while(!Q.empty())
    {
        //int cost = Q.begin()->first;
        int nod = Q.begin()->second;
        Q.erase(Q.begin());
        for (auto a:V[nod])
        {
            if(GR[nod][a])
            {
                int new_d = d[nod] + C[nod][a] + dist[nod] - dist[a];
                if(new_d < d[a])
                {
                    if (d[a] != inf)
                        Q.erase(Q.find({d[a],a}));
                    d[a] = new_d;
                    real_d[a] = real_d[nod] + C[nod][a];
                    tata[a] = nod;
                    Q.insert({d[a],a});
                }
            }
        }
    }
    for (int i = 1; i <= n; i++)
        dist[i] = real_d[i];

    if (d[D] == inf)
        return false;

        int x = D;
       int flux = inf;
        while (x != s)
        {
            flux = min(GR[tata[x]][x],flux);
            x = tata[x];
        }
        x = D;
        while (x != s)
        {
            GR[tata[x]][x] -= flux;
            GR[x][tata[x]] += flux;
            x = tata[x];
        }
        flux_max += flux*dist[D];
    return true;
}


bool Bellman_Ford(int n, int s, int D)
{
    int x;
    queue <int> Q;
    for (int i = 1; i <= n; i++)
    {
        dist[i] = inf;
    }
    dist[s] = 0;
        Q.push(s);
        while(!Q.empty())
        {
            x = Q.front();
            Q.pop();
            in_coada[x] = false;
            for (auto a:V[x])
            if (GR[x][a])
            {
                if (dist[x] + C[x][a] < dist[a])
                {
                    dist[a] = dist[x] + C[x][a];
                    if (!in_coada[a])
                    {
                        Q.push(a);
                        in_coada[a] = true;
                    }
                }
            }
        }
    if (dist[D] == inf)
        return false;
    return true;
}

int main()
{
    ios_base::sync_with_stdio(0);
    fin.tie(0); fout.tie(0);

    int n,m,s,d,x,y,c,z;
    fin >> n >> m >> s >> d;
    for (int i = 0; i < m; i++)
    {
        fin >> x >> y >> c >> z;
        GR[x][y] = c;
        C[x][y] = z;
        C[y][x] = -z;
        V[x].pb(y);
        V[y].pb(x);
    }
    Bellman_Ford(n,s,d);
    /*for (int i = 1; i <= n; i++)
    {
        cout << i << " : " << dist[i] << "\n";
    }*/
    for (; Dijkstra(n,s,d); );
    fout << flux_max;
    return 0;
}