Cod sursa(job #2275300)

Utilizator triscacezarTrisca Vicol Cezar triscacezar Data 3 noiembrie 2018 00:03:22
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#pragma GCC optimize ("O3")

#include <iostream>

#include <bits/stdc++.h>

#define Nmax 360

#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;

priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > Q;



bool Dijkstra(int n, int s, int D)

{

    for (int i = 1; i<=n; i++)

    {

        d[i] = inf;

        tata[i] = 0;

    }

    d[s] = 0; tata[s] = s;

    real_d[s] = 0;

    Q.push({0,s});

    while(!Q.empty())

    {

        int cost = Q.top().first;

        int nod = Q.top().second;

        Q.pop();

        if (d[nod] != cost)

          continue;

        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.push({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 (; Dijkstra(n,s,d); );

    fout << flux_max;

    return 0;

}