Skip to content

Commit 0149679

Browse files
Practice problems from CH7
1 parent 447c0f2 commit 0149679

7 files changed

Lines changed: 319 additions & 49 deletions

OMSCS/Courses/GA/Office Hours/2026-03-15 - TA Office Hours - Exam 2.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tags:
77
This OH covers the following strategies, outlined below. It also covers the following practice problems:
88
- [[4.3 - Squares]]
99
- [[5.9 - Properties of Weighted Undirected Graphs]]
10-
- [[7.22 - Fast Max-Flow Recomputation (TODO)]]
10+
- [[7.22 - Fast Max-Flow Recomputation]]
1111
- [[7.24 - Direct Bipartite Matching (TODO)]]
1212

1313
## Graph Strategies

OMSCS/Courses/GA/Practice Problems/7.21 - Critical Edges (TODO).md

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
tags:
3+
- OMSCS
4+
- Algorithms
5+
- Practice
6+
---
7+
# 7.21 - Critical Edges
8+
> An edge of a flow network is called critical if decreasing the capacity of this edge results in a decrease in the maximum flow. Give an efficient algorithm that finds a critical edge in a network.
9+
10+
## Exploration
11+
To find a critical edge, we need to check through the flow network to see if there are any flows that fully utilize the capacity of a given edge. If that is the case, then reducing the capacity of that edge will reduce the overall flow through the network. There is no alternate path that this unit of flow can take. If such a path exists, then the max possible flow through the flow network has not yet been achieved.
12+
13+
Actually this is not true. Just because an edge is fully saturated does not mean that it's critical. See the flow network below.
14+
15+
```mermaid
16+
graph LR
17+
S --[2]--> A
18+
S --[2]--> B
19+
A --[2]--> C
20+
B --[2]--> C
21+
C --[2]--> T
22+
```
23+
24+
One valid max flow through this network is this:
25+
26+
```mermaid
27+
graph LR
28+
S --[2]--> A
29+
S --[0]--> B
30+
A --[2]--> C
31+
B --[0]--> C
32+
C --[2]--> T
33+
```
34+
35+
$SA$ is fully utilized, but it's not a critical edge. If the capacity of $SA$ is reduced, the flow can reroute through $SB$, which is underutilized. $CT$ is fully utilized, and is in fact a critical edge, since it forms a bottleneck through $G$.
36+
37+
Let's look at the residual network for this flow. The edges are labelled `[remaining capacity / reverse capacity]`.
38+
39+
```mermaid
40+
graph LR
41+
42+
S --[0/2]--> A
43+
S --[2/0]--> B
44+
A --[0/2]--> C
45+
B --[2/0]--> C
46+
C --[0/2]--> T
47+
```
48+
49+
In the residual graph, the edges which are "at capacity" have a forward flow of 0. That's a good first indicator that the edge is critical. In this flow, those edges are $SA$, $AC$, and $CT$.
50+
51+
How is criticality visible in the residual graph? The TA mentioned that we can run DFS from a given $u$ for an at-capacity edge $(u,v)$, and seeing if $v$ is reachable. If $v$ is reachable, then $(u,v)$ is not critical. How does that make sense? I believe the rationale here is:
52+
53+
If we have a max flow through a flow network, all st-paths are at capacity. If we subsequently reduce the flow across a given edge $(u,v)$ by some minimum amount $\epsilon$, that introduces both an oversupply of flow at $u$ and a deficit of flow at $v$. These 2 issues can be symbolized by the inequalities $f_{out}(u) < f_{in}(u)$ and $f_{in}(v) < f_{out}(v)$. In the special cases where $u=s$ and/or $v=t$, the appropriate in/out-flow is $C$. For all other vertices $w$ in $G$, $f_{out}(w) = f_{in}(w)$. In order to correct this issues at $u$ and $v$, (i.e. convert those inequalities to equalities), we need to find some alternate route for the $\epsilon$ units of flow through the network from $u$ to $v$. This can be accomplished by running DFS in the residual network from $u$, and checking to see if there exists a path to $v$.
54+
55+
Let's look at $SA$. We can reduce $c_{SA}$ by 1 or 2, and the flow can bypass the edge. With $SA$'s capacity being maximized, $S$ can reach $A$ in the residual network through $(SB,BC,\overline{AC})$.
56+
57+
In practicality, we aren't saying that the $\epsilon$ units of flow needs to be strictly rerouted from $u$ to $v$ through some other pathway in the network. In the given case where $A$ is replaced by by hundreds of vertices lined up in series, we're not going to reroute the flow from $S$ to $A_1$, then back through $[A_2, A_3, ..., A_x, C]$. Instead, the process of updating the residual with the results of DFS will simply reduce the flow through the edges $[SA_1, A_1A_2,A_2A_3,...,A_xC]$, increasing the flow by the same amount through edges $[SB, BC]$. We don't actually need to perform this update on the residual network. We just need to demonstrate that it's possible.
58+
59+
For completeness, when looking at $SA$, $S$ can't reach $T$. We already know this is the case because the flow is maximized, so there's no point in checking for it. However, that doesn't matter, because that's not the question. When evaluating $CT$ for criticality, we'll find that $C$ can't reach $T$ in the residual network, therefore demonstrating that $C$ is a critical edge. This is a special case, and not a general formulation of the process. In the event that $CT$ were bisected by another vertex $D$, we'd note that $C$ cannot reach $D$ in the residual network, thereby making both $CD$ and $DT$ critical.
60+
61+
Note that this problem doesn't specify that the graph weights are integers. Therefore, we must use Edmonds-Karp, and cannot use Ford-Fulkerson.
62+
63+
## Algorithm
64+
- Run Edmonds-Karp on $G$ to produce a maximum flow through $G$.
65+
- Reconstruct the residual network $G^f$.
66+
- Initialize an empty graph $G^f$
67+
- Add all the vertices of $G$ to $G^f$
68+
- For each edge $vw \in E$
69+
- Add $vw$ to $G^f$
70+
- Add $wv$ to $G^f$
71+
- Set $c^f_{vw}=c_{vw}-f_{vw}$ (for the forward flow)
72+
- Set $c^f_{wv}=f_{vw}$ (for the reverse flow)
73+
- For each edge $uv \in E$ where $c_{uv}=f_{uv}$ (alternate check: $c^f_{uv}=0$
74+
- Run DFS from $u$ in $G^f$
75+
- Check whether $v$ is reachable ($post[v]<post[u]$)
76+
- Return $uv$ if $v$ is not reachable.
77+
78+
## Justification
79+
See above.
80+
81+
## Runtime
82+
- EK: $O(nm^2)$
83+
- Reconstruct residual flow network: $O(n+m)$
84+
- Iterate over edges: $O(m)$
85+
- Run DFS: $O(n+m)$
86+
87+
Overall:
88+
- $O(nm^2+n+m+m(n+m))$
89+
- $O(nm^2+n+m+mn+m^2)$
90+
- $O(nm^2)$

OMSCS/Courses/GA/Practice Problems/7.22 - Fast Max-Flow Recomputation (TODO).md

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
tags:
3+
- OMSCS
4+
- Algorithms
5+
- Practice
6+
---
7+
# 7.22 - Fast Max-Flow Recomputation
8+
> In a particular network $G=(V,E)$ whose edges have integer capacities $c_e$, we have already found the maximum flow $f$ from node $s$ to node $t$. However, we now find out that one of the capacity values we used was wrong: for edge $(u,v)$ we used $c_{uv}$ whereas it should have been $c_{uv}−1$. This is unfortunate because the flow $f$ uses that particular edge at full capacity: $f_{uv} = c_{uv}$.
9+
>
10+
> We could redo the flow computation from scratch, but there’s a faster way. Show how a new optimal flow can be computed in $O(|V|+ |E|)$ time.
11+
12+
13+
## Exploration
14+
This is an extension of [[7.21 - Critical Edges]] which actually requires that we update the flows. We first need to check to see if that edge was critical. This can be done by reconstructing the residual network $G^f$ and then running DFS from $u$ in $G^f$ to see if $v$ is reachable.
15+
16+
If $v$ is reachable from $u$ in $G^f$, we can use the results of DFS to update the flow. Starting from $v$, we can use $prev[]$ to retrace the steps back to $u$. This forms a uv-path in $G^f$. For each pair of vertices $a,b \in V$ encountered along the uv-path, we have an edge $e=(a,b)$ in the flow network. If the uv-path in $G^f$ traveled in the same direction of $e$ in $G$, we add 1 to $f_{ab}$. If the uv-path in $G^f$ traveled in the opposite direction of $e$ in $G$, we subtract 1 from $f_{ab}$.
17+
18+
If $v$ is **not** reachable from $v$ in $G^f$, then edge $uv$ was a critical edge. This means that the overall flow through $G$ must be reduced by 1. In order to do this, we must find a us-path in $G^f$ via DFS (generating $prev_{us}$), and a tv-path in $G^f$ via DFS (generating $prev_{tv}$). For each of these paths, we must apply a similar procedure to the one above.
19+
20+
- Starting from $s$, we can use $prev_{us}[]$ to retrace the steps "back" to $u$. Considering these vertices in reverse DFS order forms an su-path in $G^f$. For each pair of vertices $a,b \in V$ encountered along the su-path, we have an edge $e=(a,b)$ in the flow network. For each of these edges, we subtract 1 from $f_{ab}$.
21+
- Starting from $v$, we can use $prev_{tv}[]$ to retrace the steps "back" to $t$. Considering these vertices in reverse DFS order forms an vt-path in $G^f$. For each pair of vertices $a,b \in V$ encountered along the vt-path, we have an edge $e=(a,b)$ in the flow network. For each of these edges, we subtract 1 from $f_{ab}$.
22+
23+
We finish off by making sure the original mistake was accounted for in $f$, by subtracting 1 from $f_{uv}$.
24+
25+
## My Solution
26+
- Reconstruct the residual network $G^f$ from $f$, $G$, and $c$.
27+
- Run DFS from $u$ in $G^f$. We use $post[v]<post[u]$ to determine whether $v$ is reachable from $u$.
28+
- If $v$ is reachable from $u$ in $G^f$, then $uv$ is not a critical edge in $G$. This means the overall flow through flow network $G$ does not need to decrease, and can remain at $C$. We just need to find an alternate route for that unit of flow. We can retrace our steps from $v$ back to $u$ in $G$. For each edge encountered along the way, we increase or decrease the flow along that edge accordingly. If an edge in the uv-path in $G^f$ traveled in the same direction as the corresponding edge in $G$, we add 1 to that edge's flow in $f$. If an edge in the uv-path in $G^f$ traveled in the **opposite** direction as the corresponding edge in $G$, we subtract 1 from that edge's flow in $f$.
29+
- If $v$ is **not** reachable from $u$ in $G^f$, then $uv$ is a critical edge in $G$. This means the overall flow through flow network $G$ needs to be decreased by 1. Using the same $prev[]$ array, we can trace our steps from $s$ to $u$ in $G$. For each edge encountered along that path, we decrease its corresponding flow in $f$ by 1. We then run a new DFS from $t$ in $G^f$, to produce a path from $v$ to $t$. For each edge encountered along that path, we decrease the flow by 1.
30+
- We conclude by subtracting 1 from $f_e$ to account for the earlier mistake.
31+
32+
Runtime $O(n+m)$
33+
34+
## TA Solution
35+
The TA solution eliminates the conditional check as to whether $uv$ was a critical edge, and cleverly leverages the time complexity of Ford-Fulkerson.
36+
37+
- Create $G^f$ from $f$.
38+
- Run $BFS(G^f,u)$, and backtrack using $prev[s]$ to find a path that produced at least one unit of flow from $s$ to $u$. We subtract 1 from the flow for each of those edges.
39+
- Run $BFS(G^f,t)$, and backtrack using $prev[v]$ to find a path that produced at least one unit of flow from $v$ to $t$. We subtract 1 from the flow for each of those edges.
40+
- Create a new capacity table for all edges in $G$, setting $c_e'=c_e-f_e$.
41+
- We then run Ford-Fulkerson on $G$ using $c_e'$, producing $f'$.
42+
- We know that the overall flow through this new flow network ($C'$) is either 0 or 1.
43+
- If $e$ was a critical edge, the overall flow through $G$ was decreased from $C$ to $C-1$. If this is the case, $C'=0$
44+
- If $e$ was not a critical edge, the overall flow through $G$ remains at $C$. If this is the case, $C'=1$
45+
- The resulting flow is $f+f'$, with max flow $C-1+C'$
46+
47+
Runtime:
48+
- 2 rounds of BFS: $O(n+m)$
49+
- Creating the new capacity table: $O(n)$
50+
- Ford-Fulkerson: $O(mC):C=1 \therefore O(m)$
51+
52+
Since we don't know if the flow network is connected: Overall: $O(n+m)$
53+

OMSCS/Courses/GA/Practice Problems/7.24 - Direct Bipartite Matching (TODO).md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,176 @@ tags:
77
# 7.24 - Direct Bipartite Matching (TODO)
88
![[Pasted image 20260317232024.png]]
99
![[Pasted image 20260317232036.png]]
10+
11+
Covered vertices are shown with double circles. Non-covered vertices are shown as single circles. Edges that are in $M$ are shown in bold.
12+
13+
```mermaid
14+
graph TD
15+
16+
A(((A)))
17+
B(((B)))
18+
C(((C)))
19+
D((D))
20+
E(((E)))
21+
F(((F)))
22+
G((G))
23+
H(((H)))
24+
I((I))
25+
26+
A <==> E
27+
A <--> H
28+
B <--> E
29+
B <==> F
30+
B <--> G
31+
C <--> G
32+
C <==> H
33+
C <--> I
34+
D <--> F
35+
```
36+
37+
## Notes from Office Hours
38+
39+
40+
## 7.24a - Alternating Path
41+
All must start on $D$ and end on $G$ or $I$. These are the only non-covered vertices. None of these vertices can appear on the middle of the path since they're not covered, and therefore you can't arrive on an edge in $M$ and leave on an edge in $E-M$.
42+
43+
Here's all distinct alternating paths.
44+
45+
- $[D, F, B, E, A, H, C, I]$
46+
- $[D, F, B, E, A, H, C, G]$
47+
- $[D,F,B,G]$
48+
49+
## 7.24b - Maximal Matching
50+
If a bipartite graph has a matching $M$ such there exists no alternating path AP, this could mean a couple of things.
51+
52+
First, there may exist no uncovered vertices in $G$. If this is the case, there's no starting nor ending point for the AP.
53+
54+
There may exist only one vertex $v$ in $G$ which is not covered. If this were the case, then there does not exist a 2nd uncovered vertex that $v$ could connect to via an AP. Further, APs cannot be a cycle. If you have an odd-length cycle in a graph, then the graph is not bipartite. This breaks the requirement that APs be odd in length.
55+
56+
If there are any non-covered vertices which are connected, then $M$ is not maximal, because we can add the edge which connects those vertices to $M$.
57+
58+
If there does exist an alternating path in $G,M$, then we can remove it. For each edge $e$ along this path
59+
- if $e \in M$, then $M=M-\{e\}$
60+
- otherwise $M=M \cup \{e\}$
61+
62+
Take AP $[D,F,B,G]$ from 7.24a. If we apply this procedure, we take the graph from this:
63+
64+
```mermaid
65+
graph TD
66+
67+
A(((A)))
68+
B(((B)))
69+
C(((C)))
70+
D((D))
71+
E(((E)))
72+
F(((F)))
73+
G((G))
74+
H(((H)))
75+
I((I))
76+
77+
A <==> E
78+
A <--> H
79+
B <--> E
80+
B <==> F
81+
B <--> G
82+
C <--> G
83+
C <==> H
84+
C <--> I
85+
D <--> F
86+
```
87+
88+
to this
89+
90+
```mermaid
91+
graph TD
92+
93+
A(((A)))
94+
B(((B)))
95+
C(((C)))
96+
D(((D)))
97+
E(((E)))
98+
F(((F)))
99+
G(((G)))
100+
H(((H)))
101+
I((I))
102+
103+
A <==> E
104+
A <--> H
105+
B <--> E
106+
B <--> F
107+
B <==> G
108+
C <--> G
109+
C <==> H
110+
C <--> I
111+
D <==> F
112+
```
113+
114+
Each time we apply this procedure, the number of edges in $M$ increases by 1. This is because an AP must be an odd length, and must start and end with an uncovered vertex. Therefore the number of edges in an AP which are in $M$ must be one less than the number of edges in AP which are in $E-M$.
115+
116+
$$|\{e : e \in M\}|-1=|\{e : e \in (E-M)\}|:e \in AP$$
117+
118+
When we apply this procedure, the edges from AP which are not yet in M become part of M, and the edges from AP which are already in M are removed from M.
119+
120+
We know that we can always apply this procedure to an AP. Given an AP, the first and last vertices are apart of none of the edges in $M$. Each vertex in the interior of the AP is apart of only one edge in $M$. Swapping the edges from one side of each interior vertex to another will not cause any of the vertices to appear in $M$ more than once.
121+
122+
We also know that after applying this procedure to an AP, the number of uncovered vertices in the graph goes down by 2.
123+
124+
Based on all of this, suppose that we have an $M$ which is not optimal in $G$. We can always find an AP in $G,M$, and apply this procedure to increase $|M|$ by one, and decrease the number of uncovered nodes by 2. We can continue applying this procedure until 1 or 0 uncovered vertices remain. At this point, $G,M$ will have no AP, making $M$ a maximal matching of $G$.
125+
126+
## 7.24c - Finding a Matching Path
127+
Something we can do is convert $G$ to a directed graph. We can rebuild $G$ such that
128+
129+
- edges which are in $M$ only connect from a vertex in $V_2$ to a vertex in $V_1$.
130+
- edges which are **not in** $M$ only connect from a vertex in $V_1$ to a vertex in $V_2$.
131+
132+
If we apply this procedure to our example graph, we get this graph, which happens to be a DAG. Finding APs in this graph is now trivial. You can just run BFS from an uncovered node, and traceback from any reachable uncovered vertex.
133+
134+
```mermaid
135+
graph TD
136+
137+
A(((A)))
138+
B(((B)))
139+
C(((C)))
140+
D((D))
141+
E(((E)))
142+
F(((F)))
143+
G((G))
144+
H(((H)))
145+
I((I))
146+
147+
E ==> A
148+
A --> H
149+
B --> E
150+
F ==> B
151+
B --> G
152+
C --> G
153+
H ==> C
154+
C --> I
155+
D --> F
156+
```
157+
158+
If we apply this procedure to the variant of G which has no APs, you get this graph. This graph has no AP. You may notice this graph also has a cycle. Curious.
159+
160+
```mermaid
161+
graph TD
162+
163+
A(((A)))
164+
B(((B)))
165+
C(((C)))
166+
D(((D)))
167+
E(((E)))
168+
F(((F)))
169+
G(((G)))
170+
H(((H)))
171+
I((I))
172+
173+
E ==> A
174+
A --> H
175+
B --> E
176+
B --> F
177+
G ==> B
178+
C --> G
179+
H ==> C
180+
C --> I
181+
F ==> D
182+
```

OMSCS/Courses/GA/Practice Problems/Suggested MST and Max Flow Problems.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ tags:
3030
- **7.19** – Suppose someone presents you with a solution to a max-flow problem on some network.
3131
- [[7.19 - Max Flow Validation]]
3232
- **7.21** – critical edge
33-
- [[7.21 - Critical Edges (TODO)]]
33+
- [[7.21 - Critical Edges]]
3434
- **7.22** – In a particular network $G=(V,E)$ whose edges have integer capacities cece​...
35-
- [[7.22 - Fast Max-Flow Recomputation (TODO)]]
35+
- [[7.22 - Fast Max-Flow Recomputation]]
3636
- **7.24**_Direct bipartite matching._
3737
- [[7.24 - Direct Bipartite Matching (TODO)]]

0 commit comments

Comments
 (0)