/*
  * Should return path from initial node to terminal;
  * Means getting new path-backtracker
  */
 public Counter bfs(int initNode, int terminalNode) {
   Counter shortestPaths = new Counter();
   Counter currentNodes = new Counter();
   Counter newNodes = new Counter();
   shortestPaths.add(initNode, 0);
   newNodes.add(initNode, 0);
   while (!newNodes.isEmpty()) {
     currentNodes = new Counter(newNodes);
     newNodes = new Counter();
     for (int r : currentNodes.keySet()) {
       Counter row = this.getRow(r);
       for (int c : row.keySet()) {
         // Weighted case: later paths can be shorter than first path
         double pathLength = currentNodes.get(r) + row.get(c);
         if (pathLength < shortestPaths.getPath(c)) {
           newNodes.put(c, pathLength);
           shortestPaths.put(c, pathLength);
         }
       }
     }
     if (shortestPaths.getPath(terminalNode) < Double.MAX_VALUE / 2.0) {
       break;
     }
   }
   return shortestPaths;
 }
 public Counter getCol(int c) {
   Counter col = new Counter();
   for (int r : rows) {
     if (this.getRow(r).containsKey(c)) {
       col.put(r, this.get(r, c));
     }
   }
   return col;
 }
 public void set(int r, int c, double v) {
   Counter row = this.getRow(r);
   if (row.isEmpty()) {
     mat.put(r, row);
   }
   row.put(c, v);
   rows.add(r);
   cols.add(c);
 }