Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
{"dfs":{"time":"O(V+E)","space":"O(V)"},"bfs":{"time":"O(V+E)","space":"O(V)"},"dijkstra":{"time":"O((V+E) log V)","space":"O(V)"},"union_find":{"time":"O(α(n)) per operation","space":"O(V)"}}
Graph Algorithms Skill
Atomic Responsibility: Execute graph traversal and pathfinding algorithms efficiently.
defdfs_recursive(graph: Graph, start: int) -> List[int]:
"""
DFS traversal from start node.
Time: O(V+E), Space: O(V)
Args:
graph: Adjacency list representation
start: Starting node
Returns:
List of nodes in DFS order
"""
visited: Set[int] = set()
result: List[int] = []
defexplore(node: int) -> None:
if node in visited:
return
visited.add(node)
result.append(node)
for neighbor in graph.get(node, []):
explore(neighbor)
explore(start)
result
() -> []:
visited: [] = ()
result: [] = []
stack = [start]
stack:
node = stack.pop()
node visited:
visited.add(node)
result.append(node)
neighbor (graph.get(node, [])):
neighbor visited:
stack.append(neighbor)
result
return
def
dfs_iterative
graph: Graph, start: int
List
int
"""
Iterative DFS using explicit stack.
Use when: Avoiding recursion depth limits.
"""
Set
int
set
List
int
while
if
in
continue
# Add neighbors in reverse for correct order
for
in
reversed
if
not
in
return
BFS - Breadth First Search
defbfs(graph: Graph, start: int) -> List[int]:
"""
BFS traversal from start node.
Time: O(V+E), Space: O(V)
Use for: Shortest path in unweighted graph.
"""
visited = {start}
queue = deque([start])
result: List[int] = []
while queue:
node = queue.popleft()
result.append(node)
for neighbor in graph.get(node, []):
if neighbor notin visited:
visited.add(neighbor)
queue.append(neighbor)
return result
defshortest_path_unweighted(graph: Graph, start: int, end: int) -> int:
"""
Find shortest path length in unweighted graph.
Time: O(V+E), Space: O(V)
Returns:
Shortest distance, or -1 if no path exists
"""if start == end:
return0
visited = {start}
queue = deque([(start, 0)])
while queue:
node, distance = queue.popleft()
for neighbor in graph.get(node, []):
if neighbor == end:
return distance + 1if neighbor notin visited:
visited.add(neighbor)
queue.append((neighbor, distance + 1))
return -1# No path found
Dijkstra's Algorithm
defdijkstra(graph: WeightedGraph, start: int) -> Dict[int, int]:
"""
Single-source shortest paths with non-negative weights.
Time: O((V+E) log V), Space: O(V)
Args:
graph: Weighted adjacency list {node: [(neighbor, weight)]}
start: Source node
Returns:
Dictionary of shortest distances from start
Raises:
ValueError: If negative weight detected
"""
distances: Dict[int, int] = {start: 0}
pq = [(0, start)] # (distance, node)while pq:
current_dist, node = heapq.heappop(pq)
# Skip if we've found a better pathif current_dist > distances.get(node, float('inf')):
continuefor neighbor, weight in graph.get(node, []):
if weight < 0:
raise ValueError(f"Negative weight {weight} not allowed in Dijkstra")
distance = current_dist + weight
if distance < distances.get(neighbor, float('inf')):
distances[neighbor] = distance
heapq.heappush(pq, (distance, neighbor))
return distances
defdijkstra_with_path(graph: WeightedGraph, start: int, end: int) -> Tuple[int, List[int]]:
"""
Dijkstra with path reconstruction.
Returns:
Tuple of (distance, path) or (inf, []) if no path
"""
distances: Dict[int, int] = {start: 0}
predecessors: Dict[int, Optional[int]] = {start: None}
pq = [(0, start)]
while pq:
current_dist, node = heapq.heappop(pq)
if node == end:
breakif current_dist > distances.get(node, float('inf')):
continuefor neighbor, weight in graph.get(node, []):
distance = current_dist + weight
if distance < distances.get(neighbor, float('inf')):
distances[neighbor] = distance
predecessors[neighbor] = node
heapq.heappush(pq, (distance, neighbor))
# Reconstruct pathif end notin distances:
returnfloat('inf'), []
path = []
current = end
while current isnotNone:
path.append(current)
current = predecessors.get(current)
return distances[end], path[::-1]
Union-Find (Disjoint Set Union)
classUnionFind:
"""
Disjoint Set Union with path compression and union by rank.
Time: O(α(n)) per operation (nearly constant)
Space: O(n)
Use for: Connected components, cycle detection, Kruskal's MST
"""def__init__(self, n: int):
"""Initialize n disjoint sets."""self.parent = list(range(n))
self.rank = [0] * n
self.components = n
deffind(self, x: int) -> int:
"""Find root of x with path compression."""ifself.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
returnself.parent[x]
defunion(self, x: int, y: int) -> bool:
"""
Unite sets containing x and y.
Returns:
True if union performed, False if already in same set
"""
px, py = self.find(x), self.find(y)
if px == py:
returnFalse# Union by rankifself.rank[px] < self.rank[py]:
px, py = py, px
self.parent[py] = px
ifself.rank[px] == self.rank[py]:
self.rank[px] += 1self.components -= 1returnTruedefconnected(self, x: int, y: int) -> bool:
"""Check if x and y are in the same set."""returnself.find(x) == self.find(y)
defget_components(self) -> int:
"""Return number of disjoint sets."""returnself.components
Topological Sort
deftopological_sort_kahn(n: int, edges: List[Tuple[int, int]]) -> List[int]:
"""
Topological sort using Kahn's algorithm (BFS).
Time: O(V+E), Space: O(V)
Args:
n: Number of nodes (0 to n-1)
edges: List of (from, to) edges
Returns:
Topologically sorted list, or empty if cycle exists
"""
graph: Graph = {i: [] for i inrange(n)}
in_degree = [0] * n
for src, dst in edges:
graph[src].append(dst)
in_degree[dst] += 1
queue = deque([i for i inrange(n) if in_degree[i] == 0])
result: List[int] = []
while queue:
node = queue.popleft()
result.append(node)
for neighbor in graph[node]:
in_degree[neighbor] -= 1if in_degree[neighbor] == 0:
queue.append(neighbor)
# Check for cycleiflen(result) != n:
return [] # Cycle detectedreturn result