Cod sursa(job #2250717)

Utilizator vladm98Munteanu Vlad vladm98 Data 30 septembrie 2018 16:40:31
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.84 kb
#include <bits/stdc++.h>

using namespace std;

class MaxFlow
{
public:
    int GetFlow(int n, vector <pair<pair<int, int>, int>> Edges, int Source, int Target)
    {
        return SolveOneGraph(n, Edges, Source, Target);
    }

private:
    //DECLARATIONS
    vector<vector<int>> Capacity;
    vector<vector<int>> Flow;
    vector<vector<int>> Graph;
    queue<int> Bellman_Ford;
    vector <int> Father;
    int Source, Target, NumberOfNodes, MaximumFlow;
    //DECLARATIONS

    //START CLASS
    void Start (int n, vector <pair<pair<int, int>, int>> Edges, int S, int T)
    {
        MaximumFlow = 0;
        Source = S;
        Target = T;
        NumberOfNodes = n;
        Capacity.resize(NumberOfNodes + 1);
        Flow.resize(NumberOfNodes + 1);
        Graph.resize(NumberOfNodes + 1);
        Father.resize(NumberOfNodes + 1);
        for (int Node = 1; Node <= NumberOfNodes; ++Node)
        {
            Capacity[Node].resize(NumberOfNodes + 1, 0);
            Flow[Node].resize(NumberOfNodes + 1, 0);
        }
        for (auto Edge : Edges)
        {
            int From = Edge.first.first;
            int To = Edge.first.second;
            int EdgeCapacity = Edge.second;

            //NORMAL GRAPH
            Capacity[From][To] += EdgeCapacity;
            Graph[From].push_back(To);
            //NORMAL GRAPH

            //RESIDUAL GRAPH
            Graph[To].push_back(From);
            //RESIDUAL GRAPH
        }
    }
    //START CLASS

    //TRY TO PUSH MORE FLOW TO TARGET
    bool TryFlow ()
    {
        fill(Father.begin(), Father.end(), 0);
        Father[Source] = Source;
        Bellman_Ford.push(Source);
        while (Bellman_Ford.size())
        {
            int CurrentNode = Bellman_Ford.front();
            Bellman_Ford.pop();
            if (CurrentNode == Target)
                continue;
            for (auto x:Graph[CurrentNode])
            {
                if (Father[x] == 0 && Flow[CurrentNode][x] < Capacity[CurrentNode][x])
                {
                    Father[x] = CurrentNode;
                    Bellman_Ford.push(x);
                }
            }
        }
        if (Father[Target] == 0)
            return false;
        return true;
    }
    //TRY TO PUSH MORE FLOW TO TARGET

    //UPDATE FLOW
    void UpdateFlow()
    {
        for (auto x:Graph[Target])
        {
            if(Father[x] == 0) continue;
            if(Capacity[x][Target] == Flow[x][Target]) continue;
            Father[Target] = x;
            int CurrentNode = Target;
            int MinimumFlow = (1<<30);
            while (CurrentNode != Source)
            {
                MinimumFlow = min(MinimumFlow, Capacity[Father[CurrentNode]][CurrentNode] - Flow[Father[CurrentNode]][CurrentNode]);
                CurrentNode = Father[CurrentNode];
            }
            CurrentNode = Target;
            while (CurrentNode != Source)
            {
                Flow[Father[CurrentNode]][CurrentNode] += MinimumFlow;
                Flow[CurrentNode][Father[CurrentNode]] -= MinimumFlow;
                CurrentNode = Father[CurrentNode];
            }
            // assert (MinimumFlow > 0);
            MaximumFlow += MinimumFlow;
        }
    }
    //UPDATE FLOW

    //GIVE ME FLOW
    int SolveOneGraph (int n, vector <pair<pair<int, int>, int>> Edges, int Source, int Target)
    {
        Start(n, Edges, Source, Target);
        while(TryFlow())
            UpdateFlow();
        return MaximumFlow;
    }
    //GIVE ME FLOW
};

vector <pair<pair<int, int>, int>> Edges;
int main(int argc, char const *argv[])
{
    ifstream fin ("maxflow.in");
    ofstream fout ("maxflow.out");

    MaxFlow *Flow = new MaxFlow;
    int n, m;
    fin >> n >> m;
    for (int i = 1; i <= m; ++i)
    {
        int x, y, Capacity;
        fin >> x >> y >> Capacity;
        Edges.push_back({{x, y}, Capacity});
    }
    fout << Flow -> GetFlow(n, Edges, 1, n);
    return 0;
}