Pagini recente » Cod sursa (job #870937) | Cod sursa (job #1472537) | Cod sursa (job #2001583) | Cod sursa (job #2035269) | Cod sursa (job #2883151)
#include<fstream>
#include<vector>
#include<queue>
std::ifstream fin("maxflow.in");
std::ofstream fout("maxflow.out");
struct Edge
{
int destination_node,
flow,
capacity,
index_of_reverse_edge;
};
class Graph
{
public:
Graph(int const& number_of_nodes)
{
adj = new std::vector<Edge>[number_of_nodes];
this->number_of_nodes = number_of_nodes;
distance = new int[number_of_nodes];
}
// Add the edge from i to j with c capacity;
// Also add the reverse edge with 0 capacity;
inline void add_edge(int const& i, int const& j, int const& c);
inline bool bfs(int const& start, int const& finish);
inline int send_flow(int const& current_node, int const& flow, int const& finish, int placed[]);
inline int DinicMaxflow(int const& start, int const& finish);
private:
int number_of_nodes;
int* distance;
std::vector<Edge>* adj;
};
inline void Graph::add_edge(int const& i, int const& j, int const& c)
{
Edge a{ j, 0, c, adj[j].size() };
Edge b{ i, 0, 0, adj[i].size() };
adj[i].push_back(a);
adj[j].push_back(b);
}
inline bool Graph::bfs(int const& start, int const& finish)
{
for (int index = 0; index < number_of_nodes; ++index)
distance[index] = -1;
distance[start] = 0;
int current_node;
std::queue<int> Q;
Q.push(start);
while (!Q.empty())
{
current_node = Q.front(), Q.pop();
for (auto const& current_edge : adj[current_node])
{
if (distance[current_edge.destination_node] < 0 && current_edge.flow < current_edge.capacity)
{
distance[current_edge.destination_node] = distance[current_node] + 1;
Q.push(current_edge.destination_node);
}
}
}
return distance[finish] < 0 ? false : true;
}
inline int Graph::send_flow(int const& current_node, int const& flow, int const& finish, int placed[])
{
if (current_node == finish)
return flow;
for (; placed[current_node] < adj[current_node].size(); ++placed[current_node])
{
Edge& current_edge = adj[current_node][placed[current_node]];
if (distance[current_edge.destination_node] == distance[current_node] + 1 && current_edge.flow < current_edge.capacity)
{
// find minimum flow from start to finish
int curr_flow = std::min(flow, current_edge.capacity - current_edge.flow);
int temp_flow = send_flow(current_edge.destination_node, curr_flow, finish, placed);
// flow is greater than zero
if (temp_flow > 0)
{
// add flow to current edge
current_edge.flow += temp_flow;
// subtract flow from reverse edge
// of current edge
adj[current_edge.destination_node][current_edge.index_of_reverse_edge].flow -= temp_flow;
return temp_flow;
}
}
}
return 0;
}
inline int Graph::DinicMaxflow(int const& start, int const& finish)
{
if (start == finish)
return -1;
int total = 0;
while (bfs(start, finish))
{
int* placed = new int[1LL * number_of_nodes + 1]{ 0 };
while (int flow = send_flow(start, 2e9, finish, placed))
total += flow;
}
return total;
}
int main()
{
int n, m, i, j, c;
fin >> n >> m;
Graph r(n);
for (int k = 1; k <= m; ++k)
{
fin >> i >> j >> c;
r.add_edge(i - 1, j - 1, c);
}
int R = r.DinicMaxflow(0, n - 1);
if (R) fout << R;
else fout << "Apa nu ajunge!";
return 0;
}