Cod sursa(job #3184768)

Utilizator tudorcioc5Cioc Tudor tudorcioc5 Data 16 decembrie 2023 19:09:27
Problema Flux maxim Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.73 kb
#include <iostream>
#include <vector>
#include <utility>
#include <climits>
#include <deque>
#include <queue>
#include <fstream>
#include <algorithm>

using namespace std;

struct Neighbour
{
    int vertex, capacity, flow;
};


class Graph
{
private:
    static const int MAX_VERTICES = 1000;
    static const int MAX_EDGES = 5000;

    int noVertices;
    int noEdges;

    vector<vector<Neighbour>> neighbours;

public:
    Graph(const int& noVertices, const int& noEdges)
        : noVertices(noVertices), noEdges(noEdges),
          neighbours(noVertices + 1)
    {
    }

    int getNoVertices()
    {
        return noVertices;
    }

    int getNoEdges()
    {
        return noEdges;
    }


    void addNeighbour(const int& vertex, const int& neighbour_to_add, const int& capacity)
    {
        neighbours[vertex].push_back({neighbour_to_add, capacity, 0});
        neighbours[neighbour_to_add].push_back({vertex, 0, 0});
    }


    bool BFS(const int& source, const int& sink, vector<int>& parent)
    {
        parent = vector<int> (noVertices + 1);
        vector<bool> visited(noVertices + 1, false);

        queue<int> que;
        que.push(source);
        visited[source] = true;

        while (!que.empty())
        {
            int curr_vertex = que.front();
            que.pop();

            for (Neighbour neigh : neighbours[curr_vertex])
            {
                if (visited[neigh.vertex] || neigh.flow == neigh.capacity)
                    continue;

                visited[neigh.vertex] = true;
                parent[neigh.vertex] = curr_vertex;
                que.push(neigh.vertex);

                if (neigh.vertex == sink)
                    return true;
            }
        }

        return false;

    }

    int getMaxFlow(const int& source, const int& sink)
    {
        int maxFlow = 0;
        vector<int> parent;

        while(BFS(source, sink, parent))
        {
            int minFlowPath = INT_MAX;

            int curr_vertex = sink;
            int curr_parent = parent[sink];
            for ( ; curr_vertex != source; curr_vertex = curr_parent, curr_parent = parent[curr_vertex])
                for (Neighbour neigh : neighbours[curr_parent])
                {
                    if (neigh.vertex != curr_vertex)
                        continue;

                    if (neigh.capacity - neigh.flow < minFlowPath)
                        minFlowPath = neigh.capacity - neigh.flow;
                }
            
            maxFlow += minFlowPath;


            curr_vertex = sink;
            curr_parent = parent[sink];
            for ( ; curr_vertex != source; curr_vertex = curr_parent, curr_parent = parent[curr_vertex])
            {
                for (Neighbour& neigh : neighbours[curr_parent])
                {
                    if (neigh.vertex != curr_vertex)
                        continue;

                    neigh.flow += minFlowPath;
                }

                for (Neighbour& neigh : neighbours[curr_vertex])
                {
                    if (neigh.vertex != curr_parent)
                        continue;

                    neigh.flow -= minFlowPath;
                }
            }
        }

        return maxFlow;
    }


};



int main()
{
    int N, M;

    ifstream fin ("maxflow.in");
    fin>> N >> M;
    Graph graph(N, M);

    for (int i=1; i<=M; i++)
    {
        int left, right, capacity;
        fin >> left >> right >> capacity;

        graph.addNeighbour(left, right, capacity);
    }
    
    fin.close();

    ofstream fout("maxflow.out");
    fout << graph.getMaxFlow(1, N) << "\n";

    fout.close();

    return 0;
}