Cod sursa(job #2757411)

Utilizator ArkinyStoica Alex Arkiny Data 5 iunie 2021 11:06:55
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.9 kb
#include<iostream>
#include<vector>
#include<fstream>
#include<queue>
using namespace std;


struct Edge
{
    int x, y, f;
};

struct EdgeId
{
    int id, reverseId;
};

typedef vector<vector<EdgeId>> FlowGraph;


int BFS(FlowGraph flowGraph, vector<Edge> &edges, int S, int T)
{
    int N = flowGraph.size();

    vector<bool> visited(N);
    vector<EdgeId> father(N);
    vector<int> distance(N);
    for (int i = 0; i < N; ++i)
    {
        visited[i] = false;
        father[i] = { -1,-1 };
        distance[i] = 0;
    }

    queue<int> q;

    q.push(S);
    visited[S] = true;
    int minDistance = 0;
    while (q.size())
    {
        int node = q.front();

        for (auto& neighbor : flowGraph[node])
        {
            auto edge = edges[neighbor.id];

            if (!visited[edge.y] && edge.f != 0)
            {
                q.push(edge.y);
                visited[edge.y] = true;

                father[edge.y] = neighbor;

                distance[edge.y] = distance[edge.x] + 1;

                if (edge.y == T)
                {
                    minDistance = distance[edge.y];
                }
            }
        }

        q.pop();
    }

    int f = 0;

    for (auto neighbor : flowGraph[T])
    {
        auto incoming = father[edges[neighbor.reverseId].x];

        int minFlow = edges[neighbor.reverseId].f;

        if (distance[edges[neighbor.reverseId].x] == minDistance - 1)
        {
            for (; incoming.id != -1; incoming = father[edges[incoming.id].x])
            {
                minFlow = min(minFlow, edges[incoming.id].f);
            }

            edges[neighbor.reverseId].f -= minFlow;
            edges[neighbor.id].f += minFlow;

            incoming = father[edges[neighbor.reverseId].x];

            for (; incoming.id != -1; incoming = father[edges[incoming.id].x])
            {
                edges[incoming.id].f -= minFlow;
                edges[incoming.reverseId].f += minFlow;
            }


            f += minFlow;
        }
    }

    return f;
}

int EdmondKarp(FlowGraph flowGraph, vector<Edge> &edges, int S, int T)
{
    int f = 0;

    while (int l_f = BFS(flowGraph, edges, S, T))
    {
        f += l_f;
    }

    return f;
}

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

    cin.rdbuf(in.rdbuf());
    cout.rdbuf(out.rdbuf());
#endif

    int N, M;

    cin >> N >> M;

    FlowGraph graph(N+1);
    vector<Edge> edges;

    int id = 0;
    for (int i = 1; i <= M; ++i)
    {
        int x, y, c;

        cin >> x >> y >> c;

        graph[x].push_back({ id, id + 1 });
        graph[y].push_back({ id+1, id});

        edges.push_back({ x,y,c });
        edges.push_back({ y,x, 0 });

        id += 2;
    }

    cout << EdmondKarp(graph, edges, 1, N);

    return 0;
}