#include <iostream>
#include <vector>
#include <stack>
#include <limits>
using namespace std;
class Graph {
public:
int V;
vector<vector<pair<int, int>>> adj;
Graph(int V) {
this->V = V;
adj.resize(V);
}
void addEdge(int u, int v, int weight) {
adj[u].push_back({v, weight});
}
void topologicalSortUtil(int v, vector<bool> &visited, stack<int> &Stack) {
visited[v] = true;
for (auto &edge : adj[v]) {
int node = edge.first;
if (!visited[node]) {
topologicalSortUtil(node, visited, Stack); // recurse to neighbors
}
}
Stack.push(v); // push after visiting neighbors
}
void shortestPath(int start) {
stack<int> Stack;
vector<bool> visited(V, false);
for (int i = 0; i < V; i++) {
if (!visited[i]) {
topologicalSortUtil(i, visited, Stack); // get topological order
}
}
vector<int> dist(V, numeric_limits<int>::max());
dist[start] = 0; // distance to start is zero
while (!Stack.empty()) {
int u = Stack.top();
Stack.pop();
if (dist[u] != numeric_limits<int>::max()) {
for (auto &edge : adj[u]) {
int v = edge.first;
int weight = edge.second;
if (dist[v] > dist[u] + weight) {
dist[v] = dist[u] + weight; // update shorter distance
}
}
}
}
for (int i = 0; i < V; i++) {
if (dist[i] == numeric_limits<int>::max())
cout << "INF" << " ";
else
cout << dist[i] << " ";
}
cout << endl;
}
};
int main() {
Graph g(4);
g.addEdge(0, 1, 2);
g.addEdge(0, 2, 4);
g.addEdge(1, 2, 1);
g.addEdge(1, 3, 7);
g.addEdge(2, 3, 3);
g.shortestPath(0);
return 0;
}
topologicalSortUtil(node, visited, Stack); // recurse to neighbors
advance DFS to neighbors to build topological order
Stack.push(v); // push after visiting neighbors
push node after all descendants to ensure correct order
dist[start] = 0; // distance to start is zero
initialize start node distance
if (dist[u] != numeric_limits<int>::max()) {
process only nodes reachable from start
if (dist[v] > dist[u] + weight) { dist[v] = dist[u] + weight; }
relax edge to update shortest distance