Cod sursa(job #2959152)

Utilizator widzAndrei-Daniel Tava widz Data 29 decembrie 2022 22:07:56
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.99 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <limits>
#include <cmath>

//RANDOM TEST FOR A DIFFERENT PROBLEM

using namespace std;

class Graph {
private:
	int _nodes;

	unordered_map<int, int> _bfs_tree;
	unordered_set<int> _visited;
	unordered_map<int, unordered_map<int, int>> _residual_graph;

	bool BFS(const int start, const int dest) {

		queue<int> node_queue;
		_visited.clear();
		_bfs_tree.clear();

		_bfs_tree[start] = -1;
		_visited.insert(start);
		node_queue.push(start);

		while (!node_queue.empty()) {
			const int node = node_queue.front();
			node_queue.pop();
			if (node == dest)
				return true;
			for (auto& edge : _residual_graph[node]) {

				if (_visited.find(edge.first) == _visited.end() && edge.second > 0) {
					_visited.insert(edge.first);
					_bfs_tree[edge.first] = node;
					node_queue.push(edge.first);
				}
			}
		}
		return false;
	}
	void DFS(const int start) {
		_visited.insert(start);

		for (auto& edge : _residual_graph[start]) {
			if (edge.first != 0 && _visited.find(edge.first) == _visited.end() && edge.second == 1) {
				DFS(edge.first);
			}
		}
	}
public:
	Graph(int nodes, unordered_map<int, unordered_map<int, int>>& adj_list) :
		_nodes(nodes),
		_residual_graph(adj_list)
	{
		for (auto& node : _residual_graph) {
			for (const auto& edge : node.second) {
				if (_residual_graph[edge.first].find(node.first) == _residual_graph[edge.first].end())
					_residual_graph[edge.first][node.first] = 0;
			}
		}
	}

	int maxFlow(const int source, const int dest) {
		int max_flux = 0;
		while (BFS(source, dest)) {
			for (const auto& edge : _residual_graph[dest]) {

				int node = edge.first;
				if (_residual_graph[node][dest] == 0 || _visited.find(node) == _visited.end())
					continue;

				int flux = numeric_limits<int>::max();
				flux = min(flux, _residual_graph[node][dest]);

				while (_bfs_tree[node] != -1) {
					const int father = _bfs_tree[node];
					flux = min(flux, _residual_graph[father][node]);
					if (flux == 0)
						break;
					node = father;
				}

				if (flux == 0)
					continue;
				max_flux += flux;

				node = edge.first;
				_residual_graph[node][dest] -= flux;
				_residual_graph[dest][node] += flux;
				while (_bfs_tree[node] != -1) {
					const int father = _bfs_tree[node];
					_residual_graph[father][node] -= flux;
					_residual_graph[node][father] += flux;
					node = father;
				}
			}
		}
		return max_flux;
	}
	vector<int> maxCovering() {

		unordered_set<int> matched;
		vector<int> numbers;
		maxFlow(0, -2);
		for (const auto& even : _residual_graph[0]) {
			int i = even.first;
			for (const auto& odd : _residual_graph[i]) {
				int j = odd.first;
				if (j != 0 && _residual_graph[i][j] == 0) {
					matched.insert(i);
					matched.insert(j);
				}
			}
		}
		_visited.clear();
		for (auto& edge : _residual_graph[0]) {
			int node = edge.first;
			if (matched.find(node) == matched.end() && _visited.find(node) == _visited.end()) {
				DFS(node);
			}
		}
		for (auto& bruh : _residual_graph) {
			auto node = bruh.first;
			if (node == 0 || node == -2)
				continue;
			if (node % 2 == 0 && _visited.find(node) == _visited.end())
				numbers.push_back(node);
			if (node % 2 == 1 && _visited.find(node) != _visited.end())
				numbers.push_back(node);
		}
		return numbers;
	}
};

bool isPrime(int num) {
	for (int i = 2; i <= sqrt(num); ++i) {
		if (num % i == 0)
			return false;
	}
	return true;
}

int main()
{
	ifstream in("maxflow.in");

	int nodes, edges;
	in >> nodes >> edges;

	unordered_map<int,unordered_map<int, int>> adj_list;
	for(int i=0; i<edges; ++i){
		int node1, node2, capacity;
		in >> node1 >> node2 >> capacity;
		adj_list[node1][node2] = capacity;
	}
	in.close();

	Graph flux_time(nodes,adj_list);

	ofstream out("maxflow.out");
	out << flux_time.maxFlow(1,nodes)<<'\n';
	out.close();
}