Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<h2><a href="https://leetcode.com/problems/network-delay-time/">743. Network Delay Time</a></h2><h3>Medium</h3><hr><div><p>You are given a network of <code>n</code> nodes, labeled from <code>1</code> to <code>n</code>. You are also given <code>times</code>, a list of travel times as directed edges <code>times[i] = (u<sub>i</sub>, v<sub>i</sub>, w<sub>i</sub>)</code>, where <code>u<sub>i</sub></code> is the source node, <code>v<sub>i</sub></code> is the target node, and <code>w<sub>i</sub></code> is the time it takes for a signal to travel from source to target.</p>

<p>We will send a signal from a given node <code>k</code>. Return <em>the <strong>minimum</strong> time it takes for all the</em> <code>n</code> <em>nodes to receive the signal</em>. If it is impossible for all the <code>n</code> nodes to receive the signal, return <code>-1</code>.</p>

<p>&nbsp;</p>
<p><strong>Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2019/05/23/931_example_1.png" style="width: 217px; height: 239px;">
<pre><strong>Input:</strong> times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
<strong>Output:</strong> 2
</pre>

<p><strong>Example 2:</strong></p>

<pre><strong>Input:</strong> times = [[1,2,1]], n = 2, k = 1
<strong>Output:</strong> 1
</pre>

<p><strong>Example 3:</strong></p>

<pre><strong>Input:</strong> times = [[1,2,1]], n = 2, k = 2
<strong>Output:</strong> -1
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
<li><code>1 &lt;= k &lt;= n &lt;= 100</code></li>
<li><code>1 &lt;= times.length &lt;= 6000</code></li>
<li><code>times[i].length == 3</code></li>
<li><code>1 &lt;= u<sub>i</sub>, v<sub>i</sub> &lt;= n</code></li>
<li><code>u<sub>i</sub> != v<sub>i</sub></code></li>
<li><code>0 &lt;= w<sub>i</sub> &lt;= 100</code></li>
<li>All the pairs <code>(u<sub>i</sub>, v<sub>i</sub>)</code> are <strong>unique</strong>. (i.e., no multiple edges.)</li>
</ul>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from collections import defaultdict
from queue import PriorityQueue

class Solution:
def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
distance = [float('inf')] * (n+1)
graph = defaultdict(list)

for src, dest, weight in times:
graph[src].append((dest, weight))

distance[k] = 0

pq = PriorityQueue()
pq.put((0, k))

while not pq.empty():
vertex = pq.get()
node = vertex[1]
node_dist = vertex[0]

for neighbour in graph[node]:
adj_node = neighbour[0]
adj_dist = neighbour[1]

if distance[adj_node] > node_dist + adj_dist:
distance[adj_node] = node_dist + adj_dist
pq.put((distance[adj_node], adj_node))

# updating distance of node 0 as -1 cuz node 0 wont exist
distance[0] = -1
maxi = max(distance)
return maxi if maxi != float('inf') else -1




Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
'''
Kruskals algo implementation
'''
from collections import defaultdict, deque

class Kruskals:
def __init__(self, v):
self.vertices = v
self.graph = []
self.parent = [-1] * self.vertices
self.rank = [0] * self.vertices
self.min_cost = 0
self.mst = []

def add_edge(self, src, dest, weight):
self.graph.append((src, dest, weight))

def make_set(self):
for i in range(self.vertices):
self.parent[i] = i

def find_parent(self, node):
if node == self.parent[node]:
return node

return self.find_parent(self.parent[node])

def union(self, src, dest):
src = self.find_parent(src)
dest = self.find_parent(dest)

if self.rank[src] < self.rank[dest]:
self.parent[src] = dest
elif self.rank[dest] < self.rank[src]:
self.parent[dest] = src
else:
self.parent[dest] = src
self.rank[src] += 1


def construct_mst(self):
# sorting the graph by edge weights
self.graph.sort(key = lambda x: x[2])

for node in self.graph:
src = node[0]
dest = node[1]
w = node[2]
if self.find_parent(src) != self.find_parent(dest):
self.min_cost += w
# storing the nodes src and dest forming mst
self.mst.append((src, dest))

# performing union operation
self.union(src, dest)

print('MST ->', self.mst)
print('Minimum cost for MST ->', self.min_cost)


if __name__ == '__main__':
g = Kruskals(5)

g.add_edge(0, 1, 2) # src, dest, weight
g.add_edge(0, 3, 6)
g.add_edge(1, 0, 2)
g.add_edge(1, 2, 3)
g.add_edge(1, 3, 8)
g.add_edge(1, 4, 5)
g.add_edge(2, 1, 3)
g.add_edge(2, 4, 7)
g.add_edge(3, 0, 6)
g.add_edge(3, 1, 8)
g.add_edge(4, 1, 5)
g.add_edge(4, 2, 7)

g.make_set()
g.construct_mst()


Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'''
Prim's Algorithm | Brute force approach
'''

from collections import defaultdict, deque

class Prims:
def __init__(self, v):
self.vertices = v
self.graph = defaultdict(list)
self.key = [ float('inf') ] * self.vertices
self.mst = [ False ] * self.vertices
self.parent = [ -1 ] * self.vertices

def add_edge(self, src, dest, weight):
self.graph[src].append((dest, weight))

def construct_mst(self, src):
self.key[src] = 0

for node in range(self.vertices - 1):
mini = float('inf')
parent_node = src

# finding minimum edge weight from node
for i in range(self.vertices):
if (not self.mst[i]) and (self.key[i] < mini):
mini = self.key[i]
parent_node = i

self.mst[parent_node] = True

for neighbour in self.graph[parent_node]:
vertex = neighbour[0]
weight = neighbour[1]
if (not self.mst[vertex]) and (weight < self.key[vertex]):
self.parent[vertex] = parent_node
self.key[vertex] = weight

print('MST Parent Array ->', self.parent)

if __name__ == '__main__':
g = Prims(5)

g.add_edge(0, 1, 2) # src, dest, weight
g.add_edge(0, 3, 6)
g.add_edge(1, 0, 2)
g.add_edge(1, 2, 3)
g.add_edge(1, 3, 8)
g.add_edge(1, 4, 5)
g.add_edge(2, 1, 3)
g.add_edge(2, 4, 7)
g.add_edge(3, 0, 6)
g.add_edge(3, 1, 8)
g.add_edge(4, 1, 5)
g.add_edge(4, 2, 7)

g.construct_mst(0)



Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'''
Prim's Algo Efficient implementation
using Priority queue to find minimum edge weight.
'''

from collections import defaultdict, deque
from queue import PriorityQueue

class Prims2:
def __init__(self, v):
self.vertices = v
self.graph = defaultdict(list)
self.key = [ float('inf') ] * self.vertices
self.mst = [ False ] * self.vertices
self.parent = [ -1 ] * self.vertices

def add_edge(self, src, dest, weight):
self.graph[src].append((dest, weight))

def construct_mst(self, src):
# intialising priority queue to get min distance
priority_q = PriorityQueue()

self.key[src] = 0
self.parent[src] = -1
priority_q.put((0, src))

while not priority_q.empty():
parent_node = priority_q.get()[1]

for neighbour in self.graph[parent_node]:
vertex = neighbour[0]
weight = neighbour[1]

if (not self.mst[vertex]) and (weight < self.key[vertex]):
self.parent[vertex] = parent_node
self.key[vertex] = weight
priority_q.put((weight, vertex))

print(f"MST for src node '{0}'", self.parent)


if __name__ == '__main__':
g = Prims2(5)

g.add_edge(0, 1, 2) # src, dest, weight
g.add_edge(0, 3, 6)
g.add_edge(1, 0, 2)
g.add_edge(1, 2, 3)
g.add_edge(1, 3, 8)
g.add_edge(1, 4, 5)
g.add_edge(2, 1, 3)
g.add_edge(2, 4, 7)
g.add_edge(3, 0, 6)
g.add_edge(3, 1, 8)
g.add_edge(4, 1, 5)
g.add_edge(4, 2, 7)

g.construct_mst(0)