Cod sursa(job #2884044)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 2 aprilie 2022 12:18:03
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.09 kb
#include <iostream>
#include <vector> 
#include <algorithm> 
#include <string> 
#include <cassert> 
#include <algorithm> 
#include <set> 
#include <iomanip> 
#include <queue> 
#include <deque> 
#include <unordered_set> 
#include <unordered_map> 
#include <functional> 
#include <cmath> 
#include <map> 
#include <random> 
#include <chrono> 
#include <cstdio> 

bool home = true;
using namespace std;

typedef long long ll;

struct Flow {
	const int INF = (int)1e9 + 7;
	int n;

	struct Edge {
		int to, cap;
	};
	
	vector<Edge> edges;
	vector<vector<int>> g;
	vector<int> level, pt;

	Flow(int n) :
		n(n),
		g(n),
		level(n),
		pt(n) {
	}
	
	void addEdge(int a, int b, int c) {
		a--;
		b--;
		assert(0 <= a && a < n);
		assert(0 <= b && b < n);
		g[a].push_back((int)edges.size());
		g[b].push_back((int)edges.size() + 1);
		edges.push_back({ b, c });
		edges.push_back({ a, 0 });
	}

	int dfs(int a, int cur) {
		if (a == n - 1 || cur == 0) return cur;
		
		while (pt[a] < (int)g[a].size()) {
			int i = g[a][pt[a]++];
			int b = edges[i].to, cap = edges[i].cap;
			if (level[b] == 1 + level[a] && cap) {
				int x = dfs(b, min(cur, cap));
				if (x) {
					// pt[a]--;

					edges[i].cap -= x;
					edges[i ^ 1].cap += x;

					return x;
				}
			}
		}

		return 0;
	}

	int get() {
		int sol = 0;
		while (1) {
			for (int i = 0; i < n; i++) level[i] = -1, pt[i] = 0;
			level[0] = 0;
			queue<int> q;
			q.push(0);
			while (!q.empty()) {
				int a = q.front();
				q.pop();
				for (auto& i : g[a]) {
					if (edges[i].cap&&level[edges[i].to]==-1) {
						level[edges[i].to] = 1 + level[a];
						q.push(edges[i].to);
					}
				}
			}
			if (level[n - 1] == -1) break;
			while (1) {
				int x = dfs(0, INF);
				if (!x) break;
				sol += x;
			}
		}
		return sol;
	}
};

signed main() {
	freopen("maxflow.in", "r", stdin);
	freopen("maxflow.out", "w", stdout);
	int n, m;
	cin >> n >> m;
	Flow f(n);
	for (int i = 0; i < m; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		f.addEdge(a, b, c);
	}
	cout << f.get() << "\n";
}