Cod sursa(job #2889891)

Utilizator AlexNicuNicu Alexandru AlexNicu Data 13 aprilie 2022 18:21:11
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.32 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch() {
        ++sp;
        if (sp == 4096) {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (long long &n) {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};

InParser cin ( "maxflow.in" );
ofstream cout ( "maxflow.out" );

#define NMAX 1005

vector<int> G[NMAX];
int capacitate[NMAX][NMAX];
int parent[NMAX];
int viz[NMAX];

#define INF (1 << 30)
int n;

int bfs ( int source, int destination ) {
    int cur, flow;
    fill ( viz, viz + n + 1, 0 );
    viz[source] = 1;
    queue<pair<int, int>> q;
    q.push({source, INF});
    while ( !q.empty() ) {
        cur = q.front().first;
        flow = q.front().second;
        q.pop();
        if ( cur != destination ) {
            for (auto copil: G[cur]) {
                if (viz[copil] == 0 && capacitate[cur][copil]) {
                    viz[copil] = 1;
                    parent[copil] = cur;
                    int min_flow = min(flow, capacitate[cur][copil]);
                    q.push({copil, min_flow});
                }
            }
        }
    }
    return viz[destination];
}

int max_flow ( int source, int destination ) {
    int flow, new_flow, cur, prev;
    flow = 0;
    new_flow = 1;
    while ( bfs( source, destination ) ) {
        for ( auto copil : G[destination] ) {
            if (viz[copil] && capacitate[copil][destination]) {
                cur = destination;
                new_flow = INF;
                while (cur != source) {
                    prev = parent[cur];
                    new_flow = min(new_flow, capacitate[prev][cur]);
                    cur = prev;
                }
                if (new_flow) {
                    cur = destination;
                    while (cur != source) {
                        prev = parent[cur];
                        capacitate[prev][cur] -= new_flow;
                        capacitate[cur][prev] += new_flow;
                        cur = prev;
                    }
                    flow += new_flow;
                }
            }
        }
    }
    return flow;
}

int main() {
    ios_base::sync_with_stdio(false);
    cout.tie(0);
    int m, i, x, y, c;
    cin >> n >> m;
    for ( i = 1; i <= m; i++ ) {
        cin >> x >> y >> c;
        G[x].push_back(y);
        G[y].push_back(x);
        capacitate[x][y] = c;
    }
    cout << max_flow(1, n) << "\n";
    return 0;
}