Cod sursa(job #3290803)

Utilizator roberttrutaTruta Robert roberttruta Data 31 martie 2025 22:22:23
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.68 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>

#include <iostream>

using namespace std;

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

const int N = 1001;
const int inf = 9999999;

int n, m;
int lv[N], q[N], poz[N];

struct edge
{
    int to, rev, cap;
};
vector<edge> v[N];

//builds the level graph
int bfs(int s, int d)
{
    int bott = 0;
    int top = 1;
    q[bott] = s;
    lv[s] = 0;
    while(bott < top)
    {
        s = q[bott++];
        for(int i=0; i<v[s].size(); i++)
        {
            edge node = v[s][i];
            if(lv[node.to] == -1 && node.cap > 0)
            {
                lv[node.to] = lv[s] + 1;
                q[top++] = node.to;
            }
        }
    }
    return lv[d] != -1;
}

int dfs(int s, int d, int flow)
{   
    //if we reached d, we can push some flow
    if(s == d)
        return flow;

    for(int i=poz[s]; i<v[s].size(); i++)
    {
        edge node = v[s][i];
        //we only push on the level graph
        if(lv[node.to] == lv[s] + 1 && node.cap > 0)
        {
            int new_flow = min(flow, node.cap);
            new_flow = dfs(node.to, d, new_flow);
            //if we can push flow, we do it
            if(new_flow > 0)
            {
                v[s][i].cap -= new_flow;
                //track the pushed flow
                v[node.to][node.rev].cap += new_flow;
                return new_flow;
            }
        }
        //this section was fully explored we don't need to do it again on this level graph
        poz[s]++;
    }
    return 0;
}

int dinic(int s, int d)
{
    int max_flow = 0;
    int ok = 1;
    //if there is still a path from s to d
    while(ok)
    {
        //level graph in bfs order
        memset(lv, -1, N *sizeof(int));
        //optimization to ignore already searched paths in dfs
        memset(poz, 0, N *sizeof(int));
        ok = bfs(s, d);
        if(ok)
        {
            int flow = 0;
            //while we can push flow we do it
            do
            {
                //just a straight push from s to d, thee graph is explored only in depth
                flow = dfs(s, d, inf);
                max_flow += flow;
            } while (flow > 0);
        }
    }
    return max_flow;
}

int main() 
{
    fin >> n >> m;
    int x, y, c;
    for(int i=0; i<m; i++)
    {
        //we need to add a reverse edge to track the pushed flow and reroute it if necessary
        fin >> x >> y >> c;
        v[x].push_back({y, (int)v[y].size(), c});
        v[y].push_back({x, (int)v[x].size() - 1, 0});
    }
    fout << dinic(1, n);

    return 0;
}