21bce2321 Daa Da4
21bce2321 Daa Da4
Name-Rahul jain
Reg No.-21BCE2321
Steps:
1. Initialize Distances:
○ Set the distance of the source vertex to 0.
○ Set the distance of all other vertices to infinity (a very large number).
○ This ensures that the source vertex is prioritized during pathfinding.
2. Relax All Edges (|V| - 1) Times:
○ For each vertex in the graph, you repeat the edge relaxation process.
○ Relaxation involves checking each edge in the graph and updating the distance
to the destination vertex if a shorter path is found through the source vertex.
○ This is repeated |V| - 1 times because the longest possible path without a cycle in
a graph with V vertices has at most (V - 1) edges.
3. Check for Negative-Weight Cycles:
○ After relaxing all edges |V| - 1 times, the shortest path to each vertex should be
finalized.
○ To detect any negative-weight cycles, check all edges one more time.
○ If you can still relax any edge, it means that a negative-weight cycle exists in the
graph. The algorithm should report the presence of such a cycle.
4. Return Shortest Paths or Report Negative Cycle:
○ If no negative-weight cycle is detected, the algorithm will output the shortest path
from the source to all vertices.
○ If a negative cycle is detected, output that a negative-weight cycle exists.
Time Complexity:
class BellmanFord {
class Edge {
int source, destination, weight;
Edge() {
source = destination = weight = 0;
}
}
int V, E;
Edge edge[];
BellmanFord(int v, int e) {
V = v;
E = e;
edge = new Edge[e];
for (int i = 0; i < e; ++i)
edge[i] = new Edge();
}
graph.edge[1].source = 0;
graph.edge[1].destination = 2;
graph.edge[1].weight = 4;
graph.edge[2].source = 1;
graph.edge[2].destination = 2;
graph.edge[2].weight = 3;
graph.edge[3].source = 1;
graph.edge[3].destination = 3;
graph.edge[3].weight = 2;
graph.edge[4].source = 1;
graph.edge[4].destination = 4;
graph.edge[4].weight = 2;
graph.edge[5].source = 3;
graph.edge[5].destination = 2;
graph.edge[5].weight = 5;
graph.edge[6].source = 3;
graph.edge[6].destination = 1;
graph.edge[6].weight = 1;
graph.edge[7].source = 4;
graph.edge[7].destination = 3;
graph.edge[7].weight = -3;
int src = 0;
graph.BellmanFordAlgorithm(graph, src);
}
}
Output
Algorithm: Floyd-Warshall Algorithm
Purpose:
The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of vertices in a
weighted graph. This algorithm works even with negative weights, but the graph should not
have negative weight cycles.
1. Initialization:
○ Create a 2D matrix dist[][], where each element dist[i][j] represents the shortest
distance from vertex i to vertex j.
○ Initially, the matrix is filled with direct distances between the vertices. If there is
no direct edge between two vertices, the distance is initialized to infinity.
2. Iterative Update:
○ The algorithm runs through each vertex k as an intermediate point between two
vertices i and j.
○ For each pair of vertices (i, j), the algorithm checks if the path through vertex k
offers a shorter route than the previously known shortest path and updates the
matrix if necessary.
○ This is done for all vertices in the graph.
3. Negative Cycles:
○ If the diagonal of the matrix dist[i][i] ends up negative for any vertex i, then a
negative weight cycle exists, as a vertex can reach itself through a cycle with a
negative total weight.
4. Final Matrix:
○ After running the algorithm, the matrix dist[i][j] will contain the shortest distances
between every pair of vertices.
Time Complexity:
● The time complexity of the Floyd-Warshall algorithm is O(V³), where V is the number of
vertices.
○ This is because there are three nested loops that iterate over all vertices.
Code
import java.util.Arrays;
Output
Algorithm: Ford-Fulkerson Algorithm
Purpose:
The Ford-Fulkerson algorithm computes the maximum flow in a flow network. The idea is to find
valid augmenting paths in the residual graph and add flow along those paths until no more
augmenting paths can be found.
1. Initialization:
○ Start with an initial flow of 0.
○ The residual graph initially equals the original capacity graph.
2. Find Augmenting Paths:
○ While there exists an augmenting path from the source (S) to the sink (T) in the
residual graph, increase the flow.
○ An augmenting path is a path where we can push more flow (i.e., the path has
available capacity).
3. Update Residual Graph:
○ For each augmenting path found, update the flow along the path by adding the
flow to the forward edges and subtracting it from the backward edges (residual
capacity).
○ This is done to ensure that the flow conservation property holds at each vertex.
4. Terminate When No More Augmenting Paths:
○ The algorithm terminates when no more augmenting paths can be found in the
residual graph.
○ The total flow is the sum of the flows along the augmenting paths found during
the algorithm.
Time Complexity:
● O(max_flow * E), where E is the number of edges and max_flow is the maximum
possible flow in the network.
○ In each iteration, the algorithm looks for an augmenting path and adjusts the flow,
which can take O(E) time.
○ In the worst case, if we increase the flow by just 1 unit each time, we could need
O(max_flow) iterations.
Code
import java.util.LinkedList;
/* Returns true if there is a path from source 's' to sink 't' in the residual graph.
Also fills parent[] to store the path. */
boolean bfs(int rGraph[][], int s, int t, int parent[]) {
// Create a visited array and mark all vertices as not visited
boolean visited[] = new boolean[V];
for (int i = 0; i < V; ++i)
visited[i] = false;
// Update the residual capacities of the edges and reverse edges along the path
for (v = t; v != s; v = parent[v]) {
u = parent[v];
rGraph[u][v] -= pathFlow;
rGraph[v][u] += pathFlow;
}
return maxFlow;
}
Output