Cod sursa(job #2967784)

Utilizator N.B.Lnabil. N.B.L Data 20 ianuarie 2023 05:25:46
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.48 kb
//#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <climits>
#include <queue>

using namespace std;

const int MAX = 1e6;
#define  ll long long
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");

//vector <vector<int>> capacitate;
//
//int path[MAX];
//bool vizitat[MAX];
//
//int M, N;
//ll pathLength;

/// ======================== Bellmanford  O(V * E^2)
/// https://www.youtube.com/watch?v=LdOnanfc5TM&list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P&index=33
// DFS, BFS, DIJKSTRA
//int getPath(int startNode, int targetNode, int curLen, int maxCap) {
//    path[curLen] = startNode;
//
//    if (startNode == targetNode) {
//        pathLength = curLen + 1;
//        return maxCap;
//    }
//
//    int res = 0;
//    vizitat[startNode] = true;
//
//    for (int i = 0; i < N; ++i) {
//        if (vizitat[i] || capacitate[startNode][i] <= 0) continue;
//        res = getPath(i, targetNode, curLen + 1, min(maxCap, capacitate[startNode][i]));
//        if (res > 0) break;
//    }
//
//    return res;
//}
//
//ll maxFlow(int startNode, int endNode) {
//    ll totalFlow = 0;
//
//    while (true) {
//        memset(vizitat, false, sizeof (vizitat));
//        int newFlow = getPath(startNode, endNode, 0, INT_MAX);
//
//        if (newFlow <= 0)break; // once there is no paths anymore stop the algo
//
//        for (int i = 1; i < pathLength; ++i) {
//            int m = path[i - 1];
//            int n = path[i];
//            capacitate[m][n] -= newFlow;
//            capacitate[n][m] += newFlow;
//        }
//        totalFlow += newFlow;
//    }
//
//    return totalFlow;
//}


/// ======================== Capacity Scaling   O(E^2 * Log(U)) or O(E * V Log(U)) if SHORTEST PATH
// U = MAX Value ( Capacities)
// delta = smallest power of 2 less than or equal to U.
// https://www.youtube.com/watch?v=1ewLrXUz4kk&list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P&index=40
// repeatedly delta = delta / 2
vector<vector<int>> capacity;
vector<vector<int>> graph;


vector<bool> visited;
vector<int> parent;
int remainingCapacity = 0;
int M, N;


/// TLE
//ll dfs(int s, int t, int flow) {
//
//
//    if (s == t) return flow;
//
//    visited[s] = true;
//    for (int i = 0; i < capacity[s].size(); ++i) {
//        int cap = capacity[s][i];
//        if (cap >= delta && !visited[i]) {
//            parent[i] = s;
//            ll bottleNeck = dfs(i, t, min(cap, flow));
//            if (bottleNeck > 0) {
//                return bottleNeck;
//            }
//        }
//
//    }
//
//
//    return 0;
//}

// OPTIMIZARATA
bool bfs(int s, int t) {
    fill(visited.begin(), visited.end(), false);
    queue<int> q;
    q.push(s);
    visited[s] = true;
    parent[s] = -1;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
//        cout << "while BFS " <<endl;
        for (auto v: graph[u]) {
            int weight = capacity[u][v];
            if (!visited[v] && weight != 0) {
                parent[v] = u;
                if (v == t)
                    return true;
                visited[v] = true;
                q.push(v);
            }
        }
    }
    return false;
}
//4 5
//1 2 3
//1 3 5
//2 4 6
//3 4 4
//3 2 3
ll maxFlow(int s, int t) {
    ll flow = 0;

    int newFlow = INT_MAX;

    bool result = false;
    do {

        result = bfs(s, t);
        for (int v = t; v != s; v = parent[v]) {
            int u = parent[v];
            newFlow = min(newFlow, capacity[u][v]);
        }

        for (int v = t; v != s; v = parent[v]) {
            int u = parent[v];
            capacity[u][v] -= newFlow;
            capacity[v][u] += newFlow;

        }

        flow += newFlow;
    } while (result);


    return flow;
}

//4 5
//1 2 3
//1 3 5
//2 4 6
//3 4 4
//3 2 3
int main() {
//    fin >> N >> M;
//
//    capacity.resize(N + 1, vector<int>(N + 1));
//
//    graph.resize(N + 1);
//    parent.resize(N + 1);
//    visited.resize(N + 1);
//
//    for (int i = 0; i < M; ++i) {
//        int x, y;
//        int z;
//        fin >> x >> y >> z;
//        graph[x].push_back(y);
//        graph[y].push_back(x);
//        capacity[x][y] = z;
//    }
//
//    fout << maxFlow(1, N);
//


    cin >> N >> M;
    capacity.resize(N + 1, vector<int>(N + 1));

    graph.resize(N + 1);
    parent.resize(N + 1);
    visited.resize(N + 1);

    for (int i = 0; i < M; ++i) {
        int x, y;
        int z;
        cin >> x >> y >> z;
        graph[x].push_back(y);
        graph[y].push_back(x);
        capacity[x][y] = z;
    }
    cout << maxFlow(1, N);


    return 0;
}