Skip to content

Instantly share code, notes, and snippets.

@KSoto
Created August 1, 2019 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KSoto/2f30436cc1c43154fb7c3042574089af to your computer and use it in GitHub Desktop.
Save KSoto/2f30436cc1c43154fb7c3042574089af to your computer and use it in GitHub Desktop.
In a directed graph, find the max weight a route can handle
/*
(A)
^ ^ \
80/ | \30
/ | v
(D) |40 (B)
^ | /^
70\ |50//70
\ | v/
(C)
[ ["A","B",30], ["B","C",50], ["C","B",70], ["C","A",40], ["C","D",70], ["D","A",80] ]
Example route:
To go from C to A, you could use the road that allows 40lbs of weight (C->A)
OR you could use the road that allows 70lbs of weight (C->D->A)
In this case you would want the 70lb road because it can hold more weight.
Although D->A can take 80lbs, you are constrained by the lower road weight from C->D which is 70.
*/
class Road {
constructor(city,capacity,routeMax) {
this.city = city;
this.capacity = capacity;
this.routeMax = routeMax;
}
}
// Goes through all possible ways to get from source city
// to destination city.
// O(VE)
function calculateBestRoutes(input,source,dest) {
var [graph, visited] = createAdjMap(input);
var stack = [];
stack.push(new Road(source,0,Infinity));
var maxWeight = 0;
while(stack.length>0) {
var current = stack.pop();
if(current.city==dest) {
if(current.routeMax>maxWeight) {
maxWeight=current.routeMax;
}
continue;
}
visited.set(current.city,1);
if(graph.has(current.city)) {
for(var n=0; n<graph.get(current.city).length; n++) {
var neighbor = graph.get(current.city)[n];
if(visited.get(neighbor.city)==1)
continue;
var newRouteMax = Math.min(current.routeMax,neighbor.capacity);
neighbor.routeMax = newRouteMax;
stack.push(neighbor);
}
}
}
return maxWeight;
}
//O(E)
function createAdjMap(input) {
var graph = new Map();
var visited = new Map();
for(var i=0; i<input.length; i++) {
var neighbors = [];
if(graph.has(input[i][0])) {
neighbors = graph.get(input[i][0]);
}
neighbors.push(new Road(input[i][1],input[i][2],Infinity));
graph.set(input[i][0],neighbors);
visited.set(input[i][0],0);
}
return [graph, visited];
}
var inputGraph = [ ["A","B",30], ["B","C",50], ["C","B",70], ["C","A",40], ["C","D",70], ["D","A",80] ];
var [graph, visited] = createAdjMap(inputGraph);
// O(V^2)
graph.forEach(function(v1, k1, m1) {
graph.forEach(function(v2, k2, m2) {
if(k1==k2) return;
console.log(k1+"->"+k2);
var res = calculateBestRoutes(inputGraph, k1, k2);
console.log(res);
});
});
/* OUTPUT:
A->B
30
A->C
30
A->D
30
B->A
50
B->C
50
B->D
50
C->A
70
C->B
70
C->D
70
D->A
80
D->B
30
D->C
30
*/
/*
TIME COMPLEXITY:
If V is vertexes (cities) and E is edges (roads)...
we need to go through every V twice (we need to
calculate the max route weight for every possible combination).
This would give us O(V^2).
When creating the adjacency list, we need to go through all
edges which gives us O(E)
Then calculateBestRoutes goes through all the possible ways
to get from one city to another, making it O(VE). Since
we do this for every possible combination, it would
make our total complexity O( E + (V^2 * V * 2E))
which simplifies (I think) to O( E * V^3 )
SPACE COMPLEXITY:
Need to store 2 maps of size V for every city combination.
So the total size would be (2V)^2
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment