Cod sursa(job #2959464)

Utilizator VladWero08Olaeriu Vlad Mihai VladWero08 Data 31 decembrie 2022 12:27:01
Problema Flux maxim Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.06 kb
#include <bits/stdc++.h>

using namespace std;

int Nodes, Edges;
vector<int> *AdjacencyList, *InnerList;
// Cost matrix, flux matrix
long **flux, **cost;

bool FindUnsaturatedPath(int Source, int Destination, int Nodess, vector<int> *AdList, vector <int> *AdInList, long **flux, long **cost, int *dad, int *visited){
    queue <int> Q;
    int Node;

    for(int i = 0; i <= Nodess; i++){
        visited[i] = dad[i] = 0;
    }

    // Add the source in the queue
    Q.push(Source);
    // Mark the starting node as visited
    visited[Source] = 1;
    while(!Q.empty()){
        Node = Q.front();
        Q.pop();

        // For the edges leaving from Node,
        // check if it can be added more flux
        for(auto NodeNext: AdList[Node]){
            if( visited[NodeNext] != 1 && flux[Node][NodeNext] < cost[Node][NodeNext]){
                dad[NodeNext] = Node;

                // Check if the path reached the destination, and if it did
                // exit the function
                if(NodeNext == Destination)
                    return true;

                Q.push(NodeNext);
                visited[NodeNext] = 1;
            }
        }

        // For the edges coming into Node,
        // check if it can be added more flux
        for(auto NodeNext: AdInList[Node]){
            if( visited[NodeNext] != 1 && flux[Node][NodeNext] > 0){
                dad[NodeNext] = -Node;

                // Check if the path reached the destination, and if it did
                // exit the function
                if(NodeNext == Destination)
                    return true;

                Q.push(NodeNext);
                visited[NodeNext] = 1;
            }
        }
    }
    return false;
}

int FindMaxFlow(int Source, int Destination){
    int source = Source, destination = Destination, dest, maxflow = 0;
    int *dad = new int[Nodes + 1], *visited = new int [Nodes + 1];

    // While we can discover unsaturated path
    while(FindUnsaturatedPath(source, destination, Nodes, AdjacencyList, InnerList, flux, cost, dad, visited)){
        // Calculate the minimum rezidual capacity in the path that the
        // function has found
        long MRC = LONG_MAX;
        dest = destination;

        while(dest != source){
            // Edge leaving from dad
            if(dad[dest] >= 0){
                if( cost[dad[dest]][dest] - flux[dad[dest]][dest] < MRC)
                    MRC = cost[dad[dest]][dest] - flux[dad[dest]][dest];
                dest = dad[dest];
            } else{
                // Edge coming into dad
                if( flux[dest][-dad[dest]] < MRC)
                    MRC = flux[dest][-dad[dest]];
                dest = -dad[dest];
            }
        }
        dest = destination;
        while(dest != source){
            if(dad[dest] > 0){
                flux[dad[dest]][dest] += MRC;
                dest = dad[dest];
            } else{
                flux[dest][-dad[dest]] -= MRC;
                dest = -dad[dest];
            }
        }
        maxflow += MRC;
    }

    return maxflow;
}

int main() {
    int NodeX, NodeY;
    long MaxFlow;

    ////////////////////////////
    /////// READING DATA ///////
    ////////////////////////////

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

    fin >> Nodes >> Edges;

    // Resize adjacency lists
    AdjacencyList = new vector<int>[Nodes+1];
    InnerList = new vector<int>[Nodes+1];

    // Resize matrixs
    flux = new long* [Nodes+1];
    cost = new long* [Nodes+1];

    for(int i = 0; i <= Nodes; i++){
        flux[i] = new long [Nodes + 1];
        cost[i] = new long [Nodes + 1];
    }

    for(int i = 0; i < Edges; i++){
        fin >> NodeX >> NodeY >> MaxFlow;

        AdjacencyList[NodeX].push_back(NodeY);
        InnerList[NodeY].push_back(NodeX);

        // Initialize matrixs
        cost[NodeX][NodeY] = MaxFlow;
        flux[NodeX][NodeY] = 0;
    }

    fout << FindMaxFlow(1, Nodes);
    fin.close();
    fout.close();
    return 0;
}