Graphs Flashcards
Weakly Connected
- Term applies to directed graphs
- A graph that isn’t strongly connected, but would be would be connected if it were undirected
Greedy Algorithm
- An algorithm that involves making the “optimal decision” at each step
- The “optimal decision” depends on the context of problem
- Shortest distance
- Earliest time, etc.
- Ex: Dijkstra’s algorithm
- Relaxing edges is greedy
- For each edge, you compare current distance, to distance through vertex v, and choose minimum
Simple Path
- A path with no cycles
- Also, a path with no repeated vertices
Strongly Connected Graph
- Term applies to directed graphs
- There exists a path from any vertex to any other vertex
Adjacency Matrix
- An implementation of a graph using a 2D matrix edges
- Width and height of matrix is |V|
- Cells represent edges, and the indices of the cells (the rows/cols) represent vertices
- Running time is good, but space complexity is poor
- Especially useful for dense graphs or when |V|2 (size of matrix) is really small
- Cannot be used to represent a graph with parallel edges
Complexity
Time
Checking for an edge: O( 1 )
Iterating over the graph: O( v2 )
Getting all the neighbors: O( v )
Space
O(V2)
Shortest Path Problems
- Problems involving finding the shortest paths between vertices in a graph
- Refers to weighted graphs (directed or undirected)
- Variations
- Single Source Shortest Path
- All Pairs Shortest Path
- Single Destination Shortest Paths
Tree
- Connected acyclic graph
Spanning Tree
- Applies to undirected graphs
- A tree within graph that contains all vertices
- A graph can have multiple spanning trees
- The set of vertices in both graph and tree are the same
Paranthesis Theorum
- When performing DFS on a graph, the discovery and finishing times never overlap
- Consider ud, uf, and vd, vf
- Either disjoint [ud, uf], [vf, vf]
- Neither is a descendent of the other
- Or u nested in v [ud, vd, vf, uf]
- V is a descendent of U
- Or v nested in u [vd, ud, uf, vf]
- U is a descendent of V
- Either disjoint [ud, uf], [vf, vf]
Simple Graph
- a graph that does not contain loops or parallel edges
Strongly Connected Component
SCC
- strongly connected subgraph in a directed graph
Minimum Spanning Tree
- A spanning tree of a graph that has a total weight no higher than any other spanning tree in the graph
- A graph can have multiple minimum spanning trees
- Applies to weighted, undirected graphs
- A MST of an unweighted graph is just any spanning tree
Adjacency List
- An implementation of a graph using an array of linked lists of vertices
- Each element in array represents a vertex, and stores a list all edges adjacent to that vertex
- In weighted graph, nodes of list at each index also store weights (from that index to vertex)
- The list stored at each index can also (optionally) be an array, a binary tree or some other data structure
Complexity
Time
Checking for an edge: O( V ) / O ( deg(v) ) / O( lg(V) )
Iterating over all edges: O( V + E )
Getting all the neighbors: O( V )
Space
O( V + E )
* O( deg(v) ) basically means “it depends”
* O( lg(V) ) is achievable is elements are sorted, perhaps in a BST, and you use binary search
Transpose
- Reversing the direction of every edge in a directed graph
Kosaraju’s Algorithm
- Used to find strongly connected components in a directed graph
- Runs DFS twice
Steps
- Run DFS over all vertices
- Use stack to organize nodes by decreasing finish time (similar to topological sort)
- Transpose graph
- Pop vertices, run DFS on each
- Vertices reachable from this second run comprise individual scc’s (strongly connected components)
Complexity
Time
Average ⇔ Worst: O(V + E)
Space
O(V + E)
*Linear in the size of the graph
Reachable
- If a path exists from one vertex to another, it is reachable
Relaxing an edge
- Term used in shortest path algorithms
- The process of continually improving the distance estimation to some vertex through different edges
Adjacency Matrix
Directed vs Undirected Graph
- In an undirected graph, matrix will be symmetrical across diagonal
- Therefore, you should only keep one half (usually the top half)
Single Source Shortest Path
- Finding the shortest weighted path between one vertex and evey other vertex
- Or finding the shortest weighted path between one vertex to another vertex
Algorithms
- Dijkstra’s
- A*
All Pairs Shortest Paths
- Finding the shortest weighted path from every vertex to every other vertex
Algorithms
- Floyd-Warshall
Dijkstra’s Algorithm
- Single source shortest path
- Used on weighted graphs (directed or undirected)
- Graph cannot contain negative edges
Steps
- Assign every node a tentative distance-to value of infinity
- Assign every node a parent of None
- Give source distance of 0
- Add source to the priority queue
- While queue is not empty
- Remove min-distance vertex v from priority queue
- Add source to seen set
- For each neighbor u of vertex v
- If u not in seen set (if u is still in pq)
- Relax edge from v to u
- If the distance-to v + edge(v, u) is less than current distance-to u
- Update distance-to u
- Change u’s parent to v
- Add u with priority to pq (or update priority of u in pq with new distance)
- Stop upon finding destination, or when queue is empty
Complexity
Time
Average ⇔ Worst: O( |E| + |V|*log |V| )
Average ⇔ Worst: O( (|E| + |V|) * log |V| )
Space
O(V)
*First time complexity assumes fibonacci heap (constant decrease-key)
*Second time complexity assumes binary heap (log delete-min and descrease-key)
Prim’s Algorithm
- Used to find Minimum Spanning Tree
- Very similar to Dijkstra’s
- * Dijkstra PRIME: for every vertex, Priority Is My Edge
- key of priority queue is a vertex’s edge, rather than distance from source
- Basically add smallest edges one by one until tree is formed
Steps
- Initialize key (associated edge) of every vertex to infinity
- Initialize parent of every vertex to None
- Initialize key of source as 0
- Add source to pq
- While size of tree is < |V|
- Remove min element
- Add vertex and edge to MST
- For each neighbor u of v
- If u not in MST
- If edge(v, u) < key(u)
- Make v parent of u
- Update key(u) in PQ
- Keep going until PQ is empty, or until size(MST) = |V|
Complexity
Time
Average ⇔ Worst: O( |E| + |V|*log |V| )
Average ⇔ Worst: O( (|E| + |V|) * log |V| )
Space
O(V)
*First time complexity assumes fibonacci heap (constant decrease-key)
*Second time complexity assumes binary heap (log delete-min and descrease-key)