Cod sursa(job #2749713)

Utilizator borcanirobertBorcani Robert borcanirobert Data 7 mai 2021 19:22:26
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.25 kb
/// Calcularea costului minim pt. a obtine un flux maxim pe un graf orientat

#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;

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

const int MAX = 355;
const int Inf = 0x3f3f3f3f;
using VI = vector<int>;

struct Nod{
    int cost, nod;

    bool operator < ( const Nod& a ) const
    {
        return cost > a.cost;
    }
};

class Graph{
public:
    int getMinCost()
    {
        Bellman_Ford();
        while ( Dijkstra() );

        return cmin;
    }

    void Bellman_Ford()
    {
        queue<int> Q;

        memset( P, Inf, sizeof(P) );

        P[S] = 0;
        Q.push(S);

        while ( !Q.empty() )
        {
            int x = Q.front();
            Q.pop();

            for ( const int& y : G[x] )
                if ( C[x][y] )
                {
                    int cost_nou = P[x] + m[x][y];

                    if ( cost_nou >= P[y] )
                        continue;

                    P[y] = cost_nou;
                    Q.push(y);
                }
        }
    }

    bool Dijkstra()
    {
        priority_queue<Nod> Q;
        memset(Cost, Inf, sizeof(Cost));

        Cost[S] = RealCost[S] = 0;
        Q.push({0, S});

        while ( !Q.empty() )
        {
            int x = Q.top().nod;
            int c0 = Q.top().cost;
            Q.pop();

            if ( c0 != Cost[x] ) continue;

            for ( const int& y : G[x] )
                if ( C[x][y] )
                {
                    int cost_nou = Cost[x] + P[x] + m[x][y] - P[y];

                    if ( cost_nou < Cost[y] )
                    {
                        Cost[y] = cost_nou;
                        RealCost[y] = RealCost[x] + m[x][y];
                        t[y] = x;

                        Q.push({Cost[y], y});
                    }
                }
        }
        memcpy(P, RealCost, sizeof(RealCost));

        if ( Cost[D] >= Inf ) return false;

        int fc = Inf;
        for ( int i = D; i != S; i = t[i] )
            fc = min( fc, C[t[i]][i] );

        cmin += fc * RealCost[D];
        for ( int i = D; i != S; i = t[i] )
        {
            C[t[i]][i] -= fc;
            C[i][t[i]] += fc;
        }

        return true;
    }

    vector<VI> G;
    int N, S, D;
    int m[MAX][MAX];
    int C[MAX][MAX];
    int Cost[MAX]; /// costul curent
    int P[MAX];    /// costul precedent
    int RealCost[MAX];    /// costul curent real
    int t[MAX];
    int cmin;
};

Graph G;
int M;

void ReadGraph();
void Bellman_Ford();
bool Dijkstra();

int main()
{
    ReadGraph();

    

  /*  for ( int i = 1; i <= N; ++i )
        fout << P[i] << ' ';    */

    

    fout << G.getMinCost() << '\n';

    fin.close();
    fout.close();
    return 0;
}

void ReadGraph()
{
    int x, y, z, t;

    fin >> G.N >> M >> G.S >> G.D;
    G.G = vector<VI>(G.N + 1);
    while ( M-- )
    {
        fin >> x >> y >> z >> t;

        G.G[x].push_back(y);
        G.G[y].push_back(x);
        G.m[x][y] = t;
        G.m[y][x] = -t;

        G.C[x][y] = z;
        G.C[y][x] = 0;
    }
}