Pagini recente » Cod sursa (job #194280) | Cod sursa (job #848688) | Cod sursa (job #966137) | Cod sursa (job #964851) | Cod sursa (job #2959152)
#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();
}