Advanced Graph Algorithms
Shortest Path Algorithms
Dijkstra's Algorithm
public class Dijkstra {
public Map<Integer, Integer> findShortestPaths(Graph graph, int source) {
Map<Integer, Integer> distances = new HashMap<>();
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.offer(new Node(source, 0));
distances.put(source, 0);
while (!pq.isEmpty()) {
Node current = pq.poll();
for (Edge edge : graph.getAdjacentEdges(current.vertex)) {
int newDistance = current.distance + edge.weight;
if (newDistance < distances.getOrDefault(edge.destination, Integer.MAX_VALUE)) {
distances.put(edge.destination, newDistance);
pq.offer(new Node(edge.destination, newDistance));
}
}
}
return distances;
}
}
Floyd-Warshall Algorithm
public class FloydWarshall {
public int[][] findAllPairShortestPaths(int[][] graph) {
int n = graph.length;
int[][] distances = Arrays.copyOf(graph, n);
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
distances[i][j] = Math.min(
distances[i][j],
distances[i][k] + distances[k][j]
);
}
}
}
return distances;
}
}
Minimum Spanning Tree Algorithms
Kruskal's Algorithm
public class Kruskal {
public List<Edge> findMinimumSpanningTree(List<Edge> edges, int vertices) {
Collections.sort(edges, Comparator.comparingInt(e -> e.weight));
UnionFind uf = new UnionFind(vertices);
List<Edge> mst = new ArrayList<>();
for (Edge edge : edges) {
if (uf.union(edge.source, edge.destination)) {
mst.add(edge);
}
}
return mst;
}
}
Prim's Algorithm
public class Prim {
public List<Edge> findMinimumSpanningTree(Graph graph) {
PriorityQueue<Edge> pq = new PriorityQueue<>(Comparator.comparingInt(e -> e.weight));
Set<Integer> visited = new HashSet<>();
List<Edge> mst = new ArrayList<>();
int startVertex = graph.getVertices().iterator().next();
visited.add(startVertex);
pq.addAll(graph.getAdjacentEdges(startVertex));
while (!pq.isEmpty()) {
Edge edge = pq.poll();
if (!visited.contains(edge.destination)) {
visited.add(edge.destination);
mst.add(edge);
pq.addAll(graph.getAdjacentEdges(edge.destination));
}
}
return mst;
}
}
Graph Connectivity Algorithms
Tarjan's Strongly Connected Components
public class Tarjan {
private List<List<Integer>> findStronglyConnectedComponents(Graph graph) {
int[] disc = new int[graph.vertexCount()];
int[] low = new int[graph.vertexCount()];
boolean[] stackMember = new boolean[graph.vertexCount()];
Stack<Integer> stack = new Stack<>();
List<List<Integer>> scc = new ArrayList<>();
Arrays.fill(disc, -1);
Arrays.fill(low, -1);
for (int v = 0; v < graph.vertexCount(); v++) {
if (disc[v] == -1) {
dfs(graph, v, disc, low, stackMember, stack, scc);
}
}
return scc;
}
private void dfs(Graph graph, int v, int[] disc, int[] low,
boolean[] stackMember, Stack<Integer> stack,
List<List<Integer>> scc) {
// Implementation details
}
}
Algorithm Complexity Comparison
Algorithm |
Time Complexity |
Space Complexity |
Use Case |
Dijkstra |
O((V+E)logV) |
O(V) |
Shortest path in weighted graphs |
Floyd-Warshall |
O(VĀ³) |
O(VĀ²) |
All-pairs shortest paths |
Kruskal |
O(E log E) |
O(V+E) |
Minimum spanning tree |
Prim |
O(E log V) |
O(V+E) |
Minimum spanning tree |
Graph Traversal Optimization
Bidirectional Search
public class BidirectionalSearch {
public boolean search(Graph graph, int start, int end) {
Set<Integer> forwardVisited = new HashSet<>();
Set<Integer> backwardVisited = new HashSet<>();
Queue<Integer> forwardQueue = new LinkedList<>();
Queue<Integer> backwardQueue = new LinkedList<>();
forwardQueue.add(start);
backwardQueue.add(end);
forwardVisited.add(start);
backwardVisited.add(end);
while (!forwardQueue.isEmpty() && !backwardQueue.isEmpty()) {
// Bidirectional search implementation
}
return false;
}
}
Learning with LabEx
At LabEx, we offer advanced graph algorithm workshops that help you master complex graph problem-solving techniques and improve your algorithmic thinking.