Cod sursa(job #3271683)

Utilizator Alex_AeleneiAlex Aelenei Ioan Alex_Aelenei Data 26 ianuarie 2025 21:59:47
Problema Flux maxim Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.16 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>
#include <algorithm>
#include <numeric>

using namespace std;

void bfs(int nodeCount, int startNode, int endNode, vector<vector<int>> &adjacencyMatrix, vector<vector<pair<int, int>>> &adjancencyList, vector<int> &path)
{
    vector<int> visited(nodeCount + 1, false), predecessor(nodeCount + 1, 0);
    queue<int> nodes;
    bool found = false;

    path.clear();
    nodes.push(startNode);
    visited[startNode] = true;

    while (!nodes.empty() && !found)
    {
        int node = nodes.front();
        nodes.pop();

        for (auto vertex : adjancencyList[node])
            if (!visited[vertex.first] && adjacencyMatrix[node][vertex.first] > 0)
            {
                predecessor[vertex.first] = node;
                if (vertex.first == endNode)
                {
                    found = true;
                    break;
                }
                visited[vertex.first] = true;
                nodes.push(vertex.first);
            }
    }

    if (found)
    {
        int currentNode = endNode;
        while (predecessor[currentNode])
        {
            path.push_back(currentNode);
            currentNode = predecessor[currentNode];
        }
        path.push_back(startNode);
        reverse(path.begin(), path.end());
    }
}

int fordFulkerson(int nodeCount, int startNode, int endNode, vector<vector<pair<int, int>>> &adjacencyList)
{
    vector<vector<int>> residualAdjacencyMatrix(nodeCount + 1, vector<int>(nodeCount + 1, 0));

    for (int nodeIndex = 1; nodeIndex <= nodeCount; nodeIndex++)
        for (auto vertex : adjacencyList[nodeIndex])
            residualAdjacencyMatrix[nodeIndex][vertex.first] = vertex.second;

    vector<int> path;
    int maxFlow = 0;
    while (true)
    {
        path.clear();
        bfs(nodeCount, startNode, endNode, residualAdjacencyMatrix, adjacencyList, path);
        if (path.empty())
            break;

        int pathMinimum = numeric_limits<int>::max();
        for (int pathIndex = 1; pathIndex < path.size(); pathIndex++)
        {
            int source = path[pathIndex - 1];
            int destination = path[pathIndex];
            pathMinimum = min(pathMinimum, residualAdjacencyMatrix[source][destination]);
        }

        for (int pathIndex = 1; pathIndex < path.size(); pathIndex++)
        {
            int source = path[pathIndex - 1];
            int destination = path[pathIndex];
            residualAdjacencyMatrix[source][destination] -= pathMinimum;
            residualAdjacencyMatrix[destination][source] += pathMinimum;
        }

        maxFlow += pathMinimum;
    }

    return maxFlow;
}

int main()
{
    ifstream in("maxflow.in");
    ofstream out("maxflow.out");

    int nodeCount, vertexCount, source, destination, maxFlow;
    in >> nodeCount >> vertexCount;

    vector<vector<pair<int, int>>> adjacencyList(nodeCount + 1);

    for (int vertexIndex = 1; vertexIndex <= vertexCount; vertexIndex++)
    {
        in >> source >> destination >> maxFlow;
        adjacencyList[source].push_back({destination, maxFlow});
    }

    maxFlow = fordFulkerson(nodeCount, 1, nodeCount, adjacencyList);
    out << maxFlow;
    return 0;
}