public string ShortestPath(Dictionary <string, Dictionary <string, int> > graph, string source, string destination) { // get all nodes of the graph HashSet <string> allNodes = new HashSet <string>(); foreach (string u in graph.Keys) { allNodes.Add(u); foreach (string v in graph[u].Keys) { allNodes.Add(v); } } Dictionary <string, int> distances = new Dictionary <string, int>(); distances.Add(source, 0); Dictionary <string, string> path = new Dictionary <string, string>(); List <Triple> tripleList = new List <Triple>(); // build heap with nodes that connected to source // key is the min distance of the source to the node(headNode of the triple) foreach (string u in graph[source].Keys) { int len = graph[source][u]; tripleList.Add(new Triple(u, source, len)); } HeapForTriple heap = new HeapForTriple(tripleList); heap.Heapsify(); // X stores nodes that being checked HashSet <string> X = new HashSet <string>(); X.Add(source); // loop until checking all nodes while (!X.Equals(allNodes)) { if (heap.HeapIsEmpty()) { break; } // extract node with min distance from heap Triple minTriple = heap.DeleteMin(); string minNode = minTriple.GetHeadNode(); X.Add(minNode); distances.Add(minNode, minTriple.GetLength()); path.Add(minNode, minTriple.GetTailNode()); // update key value for nodes(headNodes) that form edge with minNode(tailNode) if (graph.ContainsKey(minNode)) { foreach (string v in graph[minNode].Keys) { int newLen = distances[minNode] + graph[minNode][v]; if (!heap.ContainsNode(v)) { heap.Insert(new Triple(v, minNode, newLen)); } else { int oldLen = heap.GetLength(v); if (newLen < oldLen) { heap.Delete(v); heap.Insert(new Triple(v, minNode, newLen)); } } } } } if (!path.ContainsKey(destination)) { return("Path not exist!"); } StringBuilder sb = new StringBuilder(); string n = destination; sb.Append(n); while (path.ContainsKey(n)) { string v = path[n]; int len = graph[v][n]; sb.Insert(0, " ->(" + len + ") "); sb.Insert(0, v); n = v; } return(sb.ToString()); }