Created
August 1, 2019 20:48
-
-
Save KSoto/2f30436cc1c43154fb7c3042574089af to your computer and use it in GitHub Desktop.
In a directed graph, find the max weight a route can handle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
(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