---
# System prepended metadata

title: flow network
tags: [研究所, 資演]

---

# flow network

## 一些名詞定義

==$cut(S,T)$==

把 flow network 裡面的 vertices 分成兩部分，一部分是 $S$，另一部分是 $T = V-S$

==$net \ flow \quad f(S,T)$==

「$S$ 裡的點」到 「$T$ 裡的點」邊上的 flow
扣掉反方向 「$T$ 裡的點」到 「$S$ 裡的點」邊上的 flow

![image](https://hackmd.io/_uploads/SJHmGeWtT.png)
> 可直接看下圖例子比較清楚

![image](https://hackmd.io/_uploads/ByP17lbYp.png)

==$capacity \ of \ cut \quad c(S,T)$==

「$S$ 裡的點」到 「$T$ 裡的點」的邊的 capacity
> 可直接看上方圖

## Algo
### Ford Fulkerson

#### code
![image](https://hackmd.io/_uploads/rJ-K8l-ta.png)

code 的意義：
![image](https://hackmd.io/_uploads/SyN9exbYp.png)
> 不斷從 residual network 找 augmenting path 加入，直到沒有 augmenting path 

#### 條件 ／ 特點

- 根據 <font color = "green">max-flow-min-cut</font> Thm， ++residual network 裡沒有 augmenting path++ 等價於 ++flow 已達到 max++

- 雖然 max-flow problem 大部分的 capacity 都是整數，但是<font color = "red">++有理數++也可以</font>！
> 我們可以透過適當的 scaling transformation 把所有邊的 capacity 都調成整數


#### Time

假設經過 scaling transformation 後，++transformed network 裡的 max flow++ 是 <font color = "snake">$f^*$</font> ，則 Ford Fulkerson 的 time：

<font color = "red">$O(|E|f^*)$</font>

##### 分析

因為 Ford Fulkerson 的概念是不斷找 augmenting path 直到找不到為止，所以我們每一輪就是找一條 augmenting path，我們將$O(|E|f^*)$ 分成兩部分解釋，一是 $|E|$ 從哪來，二是 $f^*$ 從哪來：

1. $O(|E|f^*)$ 裡的<font color = "green"> $|E|$</font> 代表找的時間，不管是用 DFS 找或 BFS 找，時間都是 $O(V+E')$ ，也就是 $O(E)$

> $E'$ 就是在畫 residual network 的那些邊
> 包含：
> a. 原圖中 capacity 不是 0 的邊
>> （因為 residual network 中 capacity = 0 的邊可省略不畫）
>> 
> b. 倒退邊 

- 雖然不管是 DFS 或 BFS 都可以，但一般來說講 Ford Fulkerson 通常會假設是用 DFS ，如果強制要求用 BFS 是指 Edmonds Karp（可參考下節內容）

2.  $O(|E|f^*)$ 裡的<font color = "green"> $f^*$ </font>代表最多跑幾輪（增加幾條 augmenting path）

>$f^*$ 是指 flow 的最大值，會加一個 $*$ 是因為前面有講到，在一個 flow network 中，邊的那些 capacity 是可以不是整數，只要是有理數就行的，因為我們可以透過適當的轉換把這些有理數轉成整數，那 $f^*$ 就是轉換後最大的 flow

那為什麼最多是做 $f^*$ 輪呢？

因為既然要新增 augmenting path ，代表 flow 好歹要加 1（否則加 0 等同沒做事，就不用新增啦），所以每一輪至少加 1 的情況下，最多輪的情形就是每一輪都只加最少的量，也就是每輪都只加 1，這樣等同要做 $f^*$ 輪

---


### Edmonds Karp

#### code

![image](https://hackmd.io/_uploads/rJ-K8l-ta.png)

和 Ford Fulkerson 基本上相同，除了在第三行找 augmenting path 時把每個邊的 distance / weight 設成 1，再用 <font color = "green">BFS</font> 找 shortest path

關於為什麼要找最短的 path，可參考[這篇文章](https://www.desgard.com/algo/docs/part4/ch03/4-edmond-karp/)
> 是別人的文章，我覺得寫得很清楚，如果有不妥請告知我，謝謝～


#### 條件 ／ 特點

- augmenting path 的長度是 monotonically increasing

> monotonically increasing 定義: 
> 
> $f(n) \ is \ monotonically \ increasing$
> $if \ m \le n, \quad then \ f(m) \le \ f(n)$
>> 也就是 non-decreasing （只要沒有 decrease 即可）




#### Time

Edmonds Karp time = <font color = "red">$O(VE^2)$</font>

> 105 交 52.
> 給 Edmonds Karp time = $O(V^2E)$ 正確，不知道後來有沒有修正，還是 $O(V^2E)$ 也對？

##### 分析

因為使用 DFS 找 augmenting path，每找一條 path 需要花 DFS 的時間 = $O(E)$
> 詳細可參考上方 Ford Fulkerson

根據定理，<font color = "red">最多增加 $O(VE)$ 條 augmenting path</font>，等同最多做 $O(VE)$ 輪
> 證明在 *CLRS p.729 Thm 26.8*

做 $O(VE)$ 輪，每輪花的時間是 $O(E)$，所以時間即兩者相乘 = $O(VE^2)$

## 題目不符合 flow network 的處理

#### 處理 antiparallel 的問題

flow network 要求如果某兩點 u, v 間有一個 u 到 v 的邊
> i.e. $(u,v) \in E$

則 v 到 u 不能有邊
> i.e. $(v,u) \notin E$

我們把$(u,v)$ 和 $(v,u)$ 稱作 <font color = "snake">antiparallel</font>

如果題目給的圖有 antiparallel edges，解決方法就是在這兩個點中插入一個中介點，其中一個原本的 edge 不變，另一個改為經過這個中介點

例子：

![image](https://hackmd.io/_uploads/B1QZJeWYT.png)
> 插入中介點 $v'$

#### 處理 multisource / multisink

如果有多個 source，則加入一個 <font color = "snake">supersource</font> ，連到所有這些 souces

同理如果有多個 sink，則加入一個<font color = "snake">supersink</font>，把所有的 sinks 連到這個 supersink

- 且 capacity 都設 $\infty$

例子：

![image](https://hackmd.io/_uploads/SkTXegWFT.png)

