using System;
using System.Collections.Generic;
class GfG{
// Function to construct adjacency
static List<int[]>[] constructAdj(int[,] edges, int V){
// adj[u] = list of {v, wt}
List<int[]>[] adj = new List<int[]>[V];
for (int i = 0; i < V; i++)
adj[i] = new List<int[]>();
// number of edges
int E = edges.GetLength(0);
for (int i = 0; i < E; i++){
int u = edges[i, 0];
int v = edges[i, 1];
int wt = edges[i, 2];
adj[u].Add(new int[] { v, wt });
adj[v].Add(new int[] { u, wt });
}
return adj;
}
// Custom comparer for SortedSet to act as a priority queue
class PairComparer : IComparer<int[]>{
public int Compare(int[] a, int[] b){
// Compare by distance
if (a[0] != b[0]) return a[0] - b[0];
// Tie breaker by node id
return a[1] - b[1];
}
}
// Returns shortest distances from src to all other vertices
static int[] shortestPath(int V, int[,] edges, int src){
// Create adjacency list
List<int[]>[] adj = constructAdj(edges, V);
// Use SortedSet as a min-priority queue
var pq = new SortedSet<int[]>(new PairComparer());
// Create a vector for distances and initialize all
// distances as infinite
int[] dist = new int[V];
for (int i = 0; i < V; i++)
dist[i] = int.MaxValue;
// Insert source itself in priority queue and initialize
// its distance as 0.
pq.Add(new int[] { 0, src });
dist[src] = 0;
// Looping till priority queue becomes empty
while (pq.Count > 0){
// The first vertex in pair is the minimum distance
// vertex, extract it from priority queue.
int[] top = GetAndRemoveFirst(pq);
int u = top[1];
// Get all adjacent of u.
foreach (var x in adj[u]){
// Get vertex label and weight of current
// adjacent of u.
int v = x[0];
int weight = x[1];
// If there is shorter path to v through u.
if (dist[v] > dist[u] + weight){
// Remove old pair if it exists
if (dist[v] != int.MaxValue)
pq.Remove(new int[] { dist[v], v });
// Updating distance of v
dist[v] = dist[u] + weight;
pq.Add(new int[] { dist[v], v });
}
}
}
// Return the shortest distance array
return dist;
}
// Helper to remove and return the first element from SortedSet
static int[] GetAndRemoveFirst(SortedSet<int[]> set){
var first = set.Min;
set.Remove(first);
return first;
}
// Driver program to test methods of graph class
static void Main(string[] args){
int V = 5;
int src = 0;
// edge list format: {u, v, weight}
int[,] edges = {{0, 1, 4}, {0, 2, 8}, {1, 4, 6},
{2, 3, 2}, {3, 4, 10}};
int[] result = shortestPath(V, edges, src);
// Print shortest distances in one line
foreach (int dist in result)
Console.Write(dist + " ");
}
}