Cod sursa(job #2958716)

Utilizator andlftLefter Andrei andlft Data 27 decembrie 2022 21:59:22
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.24 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

class Graph
{
private:
    int minCost = 0;
    int localFlow = (1<<30);
    vector<int> parent;
    vector<bool> inQueue;
    vector<vector<int>> graph;
    vector<vector<int>> capacity;
    vector<vector<int>> cost;
    int noOfVertices;
    int noOfEdges;
    int startVertex;
    int endVertex;
    int CostFromStartToEnd;

public:
    Graph(int n, int m, int start, int end)
    {
        noOfVertices = n;
        noOfEdges = m;
        startVertex = start;
        endVertex = end;
        graph.resize(n+1);
        capacity.resize(n+1);
        cost.resize(n+1);
        for (int i = 1; i <=n; i++)
        {
            capacity[i].resize(n+1, 0);
            cost[i].resize(n+1, 0);
        }
        parent.resize(n+1, 0);
        inQueue.resize(n+1, 0);
    }

    void readEdges()
    {
        for(int i = 1; i <= noOfEdges; i++)
        {
            int x, y, w, z;
            fin >> x >> y >> w >> z;
            capacity[x][y] = w;
            cost[x][y] = z;
            cost[y][x] = -z;
            graph[x].push_back(y);
            graph[y].push_back(x);

        }
    }

    bool BellmanFord()
    {
        inQueue.resize(noOfVertices + 1, 0);
        vector<int> BFdistance(noOfVertices+1, 1<<30);
        queue<int> que;

        que.push(startVertex);
        BFdistance[startVertex] = 0;
        parent[startVertex] = 0;
        inQueue[startVertex] = 1;

        while (!que.empty())
        {
            int front = que.front();
            que.pop();
            inQueue[front] = 0;

            for(auto nvertex : graph[front])
            {
                if(capacity[front][nvertex] != 0 && BFdistance[front] + cost[front][nvertex] < BFdistance[nvertex])
                {
                    parent[nvertex] = front;
                    BFdistance[nvertex] = BFdistance[front] + cost[front][nvertex];

                    if(!inQueue[nvertex])
                    {
                        que.push(nvertex);
                        inQueue[nvertex] = 1;
                    }
                }
            }
        }
        CostFromStartToEnd = BFdistance[endVertex];
        return BFdistance[endVertex] == 1<<30;
    }

    int getMinCost()
    {
        while (!this->BellmanFord())
        {
            localFlow = (1<<30);
            int vrtx = endVertex;
            while (vrtx != startVertex)
            {
                localFlow = min(localFlow, capacity[parent[vrtx]][vrtx]);
                vrtx = parent[vrtx];
            }
            vrtx = endVertex;
            while (vrtx != startVertex)
            {
                capacity[parent[vrtx]][vrtx] -= localFlow;
                capacity[vrtx][parent[vrtx]] += localFlow;
                vrtx = parent[vrtx];
            }
            minCost += localFlow * CostFromStartToEnd;
        }

        return minCost;
    }

};

int main()
{
    int n, m, start, end;
    fin>>n>>m>>start>>end;
    Graph graph (n,m, start, end);
    graph.readEdges();
    int result = graph.getMinCost();
    fout<<result;
    return 0;
}