forked from avinash3005/Hacktoberfest2024_avi_1
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FordFulkersonAlgorithm.cpp
147 lines (122 loc) · 4.5 KB
/
FordFulkersonAlgorithm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <iostream>
#include <limits.h>
#include <queue>
#include <vector>
using namespace std;
// A class to represent a graph
class Graph {
int V; // Number of vertices
vector<vector<int>> capacity; // Capacity of edges
vector<vector<int>> adj; // Adjacency list
public:
Graph(int V) : V(V), capacity(V, vector<int>(V, 0)), adj(V) {}
// Function to add an edge to the graph
void addEdge(int u, int v, int cap) {
capacity[u][v] = cap;
adj[u].push_back(v);
adj[v].push_back(u); // Add reverse edge for residual graph
}
// A breadth-first search to check if there is a path from source to sink
bool bfs(vector<vector<int>>& residual, int s, int t, vector<int>& parent) {
vector<bool> visited(V, false);
queue<int> q;
q.push(s);
visited[s] = true;
parent[s] = -1;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v : adj[u]) {
if (!visited[v] && residual[u][v] > 0) {
parent[v] = u;
if (v == t) return true;
q.push(v);
visited[v] = true;
}
}
}
return false;
}
// Ford-Fulkerson algorithm for computing maximum flow
int fordFulkerson(int source, int sink) {
int u, v;
vector<vector<int>> residual = capacity;
vector<int> parent(V);
int maxFlow = 0;
// Augment flow while there is a path from source to sink
while (bfs(residual, source, sink, parent)) {
cout << "Path found from " << source << " to " << sink << endl; // Debug output
int pathFlow = INT_MAX;
// Find the maximum flow through the path found.
for (v = sink; v != source; v = parent[v]) {
u = parent[v];
pathFlow = min(pathFlow, residual[u][v]);
}
// Update residual capacities of the edges and reverse edges
for (v = sink; v != source; v = parent[v]) {
u = parent[v];
residual[u][v] -= pathFlow;
residual[v][u] += pathFlow;
}
// Add path flow to overall flow
maxFlow += pathFlow;
}
cout << "The maximum possible flow is " << maxFlow << endl;
printFlowValues(residual, source);
printMinCut(residual, source);
return maxFlow;
}
// Print the flow values along the edges
void printFlowValues(const vector<vector<int>>& residual, int source) {
cout << "Flow values along the edges: " << endl;
for (int u = 0; u < V; u++) {
for (int v : adj[u]) {
if (capacity[u][v] > 0 && residual[u][v] < capacity[u][v]) {
cout << "Edge (" << u << " -> " << v << "): Flow = "
<< capacity[u][v] - residual[u][v] << " / Capacity = " << capacity[u][v] << endl;
}
}
}
}
// Use DFS to print the edges that define the minimum cut
void printMinCut(const vector<vector<int>>& residual, int source) {
vector<bool> visited(V, false);
dfs(residual, source, visited);
cout << "Edges in the Minimum Cut: " << endl;
for (int u = 0; u < V; u++) {
for (int v : adj[u]) {
if (visited[u] && !visited[v] && capacity[u][v]) {
cout << u << " -> " << v << endl;
}
}
}
}
// DFS for marking reachable vertices
void dfs(const vector<vector<int>>& residual, int u, vector<bool>& visited) {
visited[u] = true;
for (int v : adj[u]) {
if (!visited[v] && residual[u][v] > 0) {
dfs(residual, v, visited);
}
}
}
int size() const { return V; } // Function to get the number of vertices
};
int main() {
// Define the number of vertices
int V = 4; // Example: 4 vertices
// Create a graph
Graph g(V);
// Define edges and their capacities (example edges)
g.addEdge(0, 1, 10);
g.addEdge(0, 2, 5);
g.addEdge(1, 2, 15);
g.addEdge(1, 3, 10);
g.addEdge(2, 3, 10);
cout << "Graph created with " << g.size() << " vertices." << endl;
int source = 0; // Assuming source node is 0
int sink = g.size() - 1; // Assuming sink node is the last node
cout << "Running Ford-Fulkerson from source " << source << " to sink " << sink << "..." << endl;
g.fordFulkerson(source, sink);
return 0;
}