Cod sursa(job #2205735)

Utilizator Andreiii500Andrei Puiu Andreiii500 Data 20 mai 2018 02:56:46
Problema Flux maxim Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.41 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
using namespace std;

ifstream in("maxflow.in");

const int INF = 110001;
const int N = 1001;
const int START_NODE = 1;
int END_NODE;

struct edge{
    int current_flow = 0;
    int max_flow;
    bool edge_exists = false;
};

edge edges[N][N];
int n,m;

int node_path_colors[N];
int prev_path_node[N];
int crt_path_color = 0;

void find_augmenting_path_flow_value(int crt_node, int crt_path_color, int node_path_colors[]){
    //cout<<"Visiting "<<crt_node<<"\n";
    node_path_colors[crt_node] = crt_path_color;
    for(int i=1; i<=n; ++i)
        if(node_path_colors[i] != crt_path_color && /// Node hasn't been visited
           ((edges[crt_node][i].edge_exists && edges[crt_node][i].current_flow < edges[crt_node][i].max_flow) /// Can cross forwards
           || (edges[i][crt_node].edge_exists && edges[i][crt_node].current_flow > 0))) /// Can cross backwards
        {
            prev_path_node[i] = crt_node;
            find_augmenting_path_flow_value(i, crt_path_color, node_path_colors);
        }
}

int main()
{
    /// Read
    freopen("maxflow.out", "w", stdout);
    in>>n>>m;
    END_NODE = n;
    for(int i=0; i<m; ++i){
        int from, to, capacity;
        in>>from>>to>>capacity;

        edges[from][to].max_flow = capacity;
        edges[from][to].edge_exists = true;
    }

    /// Solve
    int maxFlow = 0;
    while(1){
        find_augmenting_path_flow_value(START_NODE, ++crt_path_color, node_path_colors);
        if(node_path_colors[n] != crt_path_color) /// Final node hasn't been reached
            break;

        int crtNode;
        int augmenting_flow = INF;

        /// Find the augmenting flow
        crtNode = n;
        while(crtNode != START_NODE){
            int prevNode = prev_path_node[crtNode];
            int crt_augmenting_flow = INF;

            if(edges[prevNode][crtNode].current_flow < edges[prevNode][crtNode].max_flow) /// Forward flow
                crt_augmenting_flow = edges[prevNode][crtNode].max_flow - edges[prevNode][crtNode].current_flow;
            else if(edges[crtNode][prevNode].current_flow > 0) /// Backwards flow
                crt_augmenting_flow = edges[crtNode][prevNode].current_flow;
            else /// Can't add a flow
                assert(false); /// We have chained the two nodes because there is a flow we can add

            augmenting_flow = min(augmenting_flow, crt_augmenting_flow);

            crtNode = prevNode;
        }

        /// Add augmenting flow to our path
        crtNode = n;
        //cout<<crtNode<<" ";
        while(crtNode != START_NODE){
            int prevNode = prev_path_node[crtNode];
            if(edges[prevNode][crtNode].current_flow < edges[prevNode][crtNode].max_flow) /// Forward flow
                edges[prevNode][crtNode].current_flow += augmenting_flow;
            else if(edges[crtNode][prevNode].current_flow > 0) /// Backwards flow
                edges[crtNode][prevNode].current_flow -= augmenting_flow;
            else /// Can't add a flow
                assert(false); /// We have chained the two nodes because there is a flow we can add

            crtNode = prevNode;
            //cout<<crtNode<<" ";
        }
        //cout<<"\n";
        maxFlow += augmenting_flow;
    }
    //cout<<"Max flow = "<<maxFlow<<"\n";
    cout<<maxFlow;

    return 0;
}