<commit_before>#pragma once
#include <cstddef>
#include <cstring>
#include <limits>
#include <vector>

#include "queue.hpp"

template<typename T>
class DinicFlow {
public:
	class Edge {
	public:
		Edge(const size_t from, const size_t to, const T capacity, const T flow) : from(from), to(to), cap(capacity), flow(flow) {}

		size_t from;
		size_t to;
		T cap;
		T flow;
	};

	DinicFlow(const size_t n) : graph(n), queue(n), pointer(n), dist(n), used(n) {}

	void add_directed_edge(const size_t from, const size_t to, const T capacity) {
		return add_bidirectional_edge(from, to, capacity, 0);
	}

	void add_bidirectional_edge(size_t from, size_t to, T capacity, T backward_capacity) {
		push_edge(from, to, capacity, 0);
		push_edge(to, from, backward_capacity, 0);
	}

	Edge get_edge(const size_t id) const {
		return edges[id];
	}

	static T weight_infinity() {
		return std::numeric_limits<T>::max() / 2;
	}

	T findFlow(const size_t from, const size_t to, const T infinity = weight_infinity()) {
		T flow = 0;
		while (bfs(from, to)) {
			pointer.assign(pointer.size(), 0);
			while (const T pushed = dfs(from, to, infinity)) {
				flow += pushed;
			}
		}
		return flow;
	}

	size_t edges_count() const {
		return edges.size();
	}

private:
	void push_edge(const size_t from, const size_t to, const T capacity, const T backwardCapacity) {
		graph[from].emplace_back(edges.size());
		edges.emplace_back(from, to, capacity, 0);
	}

	bool bfs(const size_t from, const size_t to) {
		used.assign(used.size(), false);
		size_t qh = 0, qt = 0;
		queue.clear();
		queue.push(from);
		used[from] = true;
		while (!queue.empty()) {
			const size_t vertex = queue.pop_front();
			for (const size_t id : graph[vertex]) {
				Edge& edge = edges[id];
				if (used[edge.to] || edge.cap == edge.flow) {
					continue;
				}
				used[edge.to] = true;
				dist[edge.to] = dist[vertex] + 1;
				queue.push(edge.to);
			}
		}
		return used[to];
	}

	T dfs(const size_t vertex, const size_t to, const T mx) {
		if (mx == 0 || vertex == to) {
			return mx;
		}
		for (size_t& i = pointer[vertex]; i < graph[vertex].size(); ++i) {
			const size_t id = graph[vertex][i];<commit_msg>Minor fixes in DinicFlow class.<commit_after>#pragma once
#include <cstddef>
#include <cstring>
#include <limits>
#include <vector>

#include "queue.hpp"

template<typename T>
class DinicFlow {
public:
	class Edge {
	public:
		Edge(const size_t from, const size_t to, const T capacity, const T flow) : from(from), to(to), cap(capacity), flow(flow) {}

		size_t from;
		size_t to;
		T cap;
		T flow;
	};

	DinicFlow(const size_t n) : graph(n), queue(n), pointer(n), dist(n), used(n) {}

	void add_directed_edge(const size_t from, const size_t to, const T capacity) {
		return add_bidirectional_edge(from, to, capacity, 0);
	}

	void add_bidirectional_edge(size_t from, size_t to, T capacity, T backward_capacity) {
		push_edge(from, to, capacity, 0);
		push_edge(to, from, backward_capacity, 0);
	}

	Edge get_edge(const size_t id) const {
		return edges[id];
	}

	static T weight_infinity() {
		return std::numeric_limits<T>::max() / 2;
	}

	T findFlow(const size_t from, const size_t to, const T infinity = weight_infinity()) {
		T flow = 0;
		while (bfs(from, to)) {
			pointer.assign(pointer.size(), 0);
			while (const T pushed = dfs(from, to, infinity)) {
				flow += pushed;
			}
		}
		return flow;
	}

	size_t edges_count() const {
		return edges.size();
	}

private:
	void push_edge(const size_t from, const size_t to, const T capacity, const T backwardCapacity) {
		graph[from].emplace_back(edges.size());
		edges.emplace_back(from, to, capacity, 0);
	}

	bool bfs(const size_t from, const size_t to) {
		used.assign(used.size(), false);
		queue.clear();
		queue.push(from);
		used[from] = true;
		while (!queue.empty()) {
			const size_t vertex = queue.pop_front();
			for (const size_t id : graph[vertex]) {
				const Edge& edge = edges[id];
				if (used[edge.to] || edge.cap == edge.flow) {
					continue;
				}
				used[edge.to] = true;
				dist[edge.to] = dist[vertex] + 1;
				queue.push(edge.to);
			}
		}
		return used[to];
	}

	T dfs(const size_t vertex, const size_t to, const T mx) {
		if (mx == 0 || vertex == to) {
			return mx;
		}
		for (size_t& i = pointer[vertex]; i < graph[vertex].size(); ++i) {
			const size_t id = graph[vertex][i];
{'fraction_non_alphanumeric': 0.1477456647398844, 'fraction_numerical': 0.004624277456647399, 'mean_word_length': 3.8066666666666666, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2602693', 'n_tokens_mistral': 1794, 'n_tokens_neox': 1603, 'n_words': 447}