Cod sursa(job #2874687)

Utilizator beingsebiPopa Sebastian beingsebi Data 19 martie 2022 23:03:21
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.72 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("maxflow.in");
ofstream g("maxflow.out");
// #define f cin
// #define g cout
const int nmax = 1002;
struct Box
{
    struct Edge
    {
        int to, capacity, flow;
        Edge *residual;
        int remaining_capacity()
        {
            return capacity - flow;
        }
    } * edge;
};
int source, sink;
int n, visited[nmax], vtoken = 1, level[nmax], nexti[nmax];
vector<Box> v[nmax];
void get_graph();
bool bfs();
long long dfs();
long long dfs(int, int);
long long get_max_flow();
int32_t main()
{
    f.tie(0)->sync_with_stdio(0);
    get_graph();
    g << get_max_flow();
    return 0;
}
void get_graph()
{
    int m;
    f >> n >> m;
    source = 1;
    sink = n;
    for (int x, y, c; m; m--)
    {
        f >> x >> y >> c;
        Box to, xto;
        to.edge = new Box::Edge;
        to.edge->capacity = c;
        to.edge->flow = 0;
        to.edge->to = y;

        xto.edge = new Box::Edge;
        xto.edge->capacity = 0;
        xto.edge->flow = 0;
        xto.edge->to = x;

        to.edge->residual = xto.edge;
        xto.edge->residual = to.edge;

        v[x].push_back(to);
        v[y].push_back(xto);
    }
}
long long get_max_flow()
{
    long long max_flow = 0;
    while (bfs())
    {
        vtoken++;
        memset(nexti, 0, sizeof nexti);
        for (int minim = dfs(); minim; minim = dfs())
            max_flow += minim;
    }

    return max_flow;
}
bool bfs()
{
    static queue<int> q;
    visited[source] = vtoken;
    level[source] = 1;
    q.push(source);
    while (!q.empty())
    {
        static int ac;
        ac = q.front();
        q.pop();
        for (const Box &i : v[ac])
            if (visited[i.edge->to] != vtoken && i.edge->remaining_capacity() > 0)
            {
                visited[i.edge->to] = vtoken;
                level[i.edge->to] = level[ac] + 1;
                q.push(i.edge->to);
            }
    }
    return (visited[sink] == vtoken);
}
long long dfs()
{
    long long minim = INT_MAX - 100000;
    return dfs(source, minim);
}
long long dfs(int x, int minim)
{
    if (x == sink)
        return minim;
    for (int cap, ne; nexti[x] < (int)v[x].size(); nexti[x]++)
    {
        cap = v[x][nexti[x]].edge->remaining_capacity();
        ne = v[x][nexti[x]].edge->to;
        if (cap > 0 && level[ne] == level[x] + 1)
        {
            long long ax = dfs(ne, min(cap, minim));
            if (ax > 0)
            {
                Box::Edge *xe = v[x][nexti[x]].edge;
                xe->flow += ax;
                xe->residual->flow -= ax;
                return ax;
            }
        }
    }
    return 0;
}