Cod sursa(job #3271845)

Utilizator Alex_AeleneiAlex Aelenei Ioan Alex_Aelenei Data 27 ianuarie 2025 15:44:08
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>
#include <algorithm>
#include <numeric>

using namespace std;

void dfs(int node, int &endNode, vector<vector<int>> &adjacencyMatrix, vector<vector<int>> &adjancencyList, vector<bool> &visited, vector<int> &path, bool &found)
{
    if (found)
        return;

    visited[node] = true;
    path.push_back(node);

    if (node == endNode)
    {
        found = true;
        return;
    }

    for (auto nextNode : adjancencyList[node])
    {
        if (!visited[nextNode] && adjacencyMatrix[node][nextNode] && !found)
            dfs(nextNode, endNode, adjacencyMatrix, adjancencyList, visited, path, found);
        if (found)
            return;
    }

    path.pop_back();
}

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)), processedAdjacencyList(nodeCount + 1);

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

    vector<int> path;
    vector<bool> visited(nodeCount + 1, false);

    int maxFlow = 0;
    while (true)
    {
        bool found = false;
        path.clear();
        fill(visited.begin(), visited.end(), false);

        dfs(startNode, endNode, residualAdjacencyMatrix, processedAdjacencyList, visited, path, found);

        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;
}