# include <iostream>
# include <vector>
# include <queue>
# include <algorithm>
using namespace std;
struct Edge {
int src, dest, weight;
bool operator < ( const Edge& other) const {
return weight < other. weight;
}
} ;
class Graph {
public :
int V;
vector< Edge> edges;
Graph ( int v) : V ( v) { }
void addEdge ( int src, int dest, int weight) {
Edge edge = { src, dest, weight} ;
edges. push_back ( edge) ;
}
void primMST ( ) {
vector< int > key ( V, INT_MAX) ;
vector< int > parent ( V, - 1 ) ;
vector< bool > inMST ( V, false ) ;
key[ 0 ] = 0 ;
priority_queue< pair< int , int > , vector< pair< int , int >> , greater< pair< int , int >> > pq;
pq. push ( { 0 , 0 } ) ;
while ( ! pq. empty ( ) ) {
int u = pq. top ( ) . second;
pq. pop ( ) ;
inMST[ u] = true ;
for ( const Edge& edge : edges) {
int v = ( edge. src == u) ? edge. dest : edge. src;
int weight = edge. weight;
if ( ! inMST[ v] && weight < key[ v] ) {
key[ v] = weight;
parent[ v] = u;
pq. push ( { key[ v] , v} ) ;
}
}
}
cout << "Prim MST:" << endl;
for ( int i = 1 ; i < V; ++ i)
cout << parent[ i] << " - " << i << endl;
}
void kruskalMST ( ) {
sort ( edges. begin ( ) , edges. end ( ) ) ;
vector< int > parent ( V, - 1 ) ;
function< int ( int ) > find = [ & ] ( int i) {
while ( parent[ i] != - 1 )
i = parent[ i] ;
return i;
} ;
function< void ( int , int ) > unionSets = [ & ] ( int x, int y) {
int rootX = find ( x) ;
int rootY = find ( y) ;
parent[ rootX] = rootY;
} ;
cout << "Kruskal MST:" << endl;
for ( const Edge& edge : edges) {
int rootSrc = find ( edge. src) ;
int rootDest = find ( edge. dest) ;
if ( rootSrc != rootDest) {
cout << edge. src << " - " << edge. dest << endl;
unionSets ( rootSrc, rootDest) ;
}
}
}
void dijkstra ( int src) {
priority_queue< pair< int , int > , vector< pair< int , int >> , greater< pair< int , int >> > pq;
vector< int > dist ( V, INT_MAX) ;
dist[ src] = 0 ;
pq. push ( { 0 , src} ) ;
while ( ! pq. empty ( ) ) {
int u = pq. top ( ) . second;
pq. pop ( ) ;
for ( const Edge& edge : edges) {
if ( edge. src == u) {
int v = edge. dest;
int weight = edge. weight;
if ( dist[ u] != INT_MAX && dist[ u] + weight < dist[ v] ) {
dist[ v] = dist[ u] + weight;
pq. push ( { dist[ v] , v} ) ;
}
}
}
}
cout << "Dijkstra Shortest Paths from vertex " << src << ":" << endl;
for ( int i = 0 ; i < V; ++ i)
cout << "To " << i << ": " << dist[ i] << endl;
}
void bellmanFord ( int src) {
vector< int > dist ( V, INT_MAX) ;
dist[ src] = 0 ;
for ( int i = 1 ; i < V; ++ i) {
for ( const Edge& edge : edges) {
int u = edge. src;
int v = edge. dest;
int weight = edge. weight;
if ( dist[ u] != INT_MAX && dist[ u] + weight < dist[ v] ) {
dist[ v] = dist[ u] + weight;
}
}
}
for ( const Edge& edge : edges) {
int u = edge. src;
int v = edge. dest;
int weight = edge. weight;
if ( dist[ u] != INT_MAX && dist[ u] + weight < dist[ v] ) {
cout << "Graph contains negative weight cycle!" << endl;
return ;
}
}
cout << "Bellman-Ford Shortest Paths from vertex " << src << ":" << endl;
for ( int i = 0 ; i < V; ++ i)
cout << "To " << i << ": " << dist[ i] << endl;
}
void floydWarshall ( ) {
vector< vector< int >> dist ( V, vector < int > ( V, INT_MAX) ) ;
for ( int i = 0 ; i < V; ++ i)
dist[ i] [ i] = 0 ;
for ( const Edge& edge : edges)
dist[ edge. src] [ edge. dest] = edge. weight;
for ( int k = 0 ; k < V; ++ k) {
for ( int i = 0 ; i < V; ++ i) {
for ( int j = 0 ; j < V; ++ j) {
if ( dist[ i] [ k] != INT_MAX && dist[ k] [ j] != INT_MAX &&
dist[ i] [ k] + dist[ k] [ j] < dist[ i] [ j] ) {
dist[ i] [ j] = dist[ i] [ k] + dist[ k] [ j] ;
}
}
}
}
cout << "Floyd Shortest Paths:" << endl;
for ( int i = 0 ; i < V; ++ i) {
for ( int j = 0 ; j < V; ++ j) {
cout << dist[ i] [ j] << "\t" ;
}
cout << endl;
}
}
} ;
int main ( ) {
Graph g ( 6 ) ;
g. addEdge ( 0 , 1 , 4 ) ;
g. addEdge ( 0 , 2 , 3 ) ;
g. addEdge ( 1 , 2 , 1 ) ;
g. addEdge ( 1 , 3 , 2 ) ;
g. addEdge ( 2 , 3 , 4 ) ;
g. addEdge ( 3 , 4 , 2 ) ;
g. addEdge ( 4 , 5 , 6 ) ;
g. primMST ( ) ;
g. kruskalMST ( ) ;
g. dijkstra ( 0 ) ;
g. bellmanFord ( 0 ) ;
g. floydWarshall ( ) ;
return 0 ;
}