\(
\newcommand{\ord}[1]{\mathcal{O}\left(#1\right)}
\newcommand{\abs}[1]{\lvert #1 \rvert}
\newcommand{\floor}[1]{\lfloor #1 \rfloor}
\newcommand{\ceil}[1]{\lceil #1 \rceil}
\newcommand{\opord}{\operatorname{\mathcal{O}}}
\newcommand{\fail}{\operatorname{\mathcal{F}}}
\newcommand{\flk}{\operatorname{\mathfrak{F}}}
\newcommand{\suf}{\operatorname{\sigma}}
\newcommand{\rank}{\operatorname{\mathcal{R}}}
\newcommand{\sa}{\operatorname{\mathcal{SA}}}
\newcommand{\hei}{\operatorname{\mathcal{H}}}
\newcommand{\edps}{\operatorname{\mathcal{E}}}
\newcommand{\mx}{\operatorname{\mathcal{M}}}
\newcommand{\argmax}{\operatorname{arg\,max}}
\newcommand{\cons}[1]{\left[ \: #1 \: \right]}
\newcommand{\str}[1]{\texttt{"#1"}}
\)
圖論關鍵
- 知識 - 多記結論
- 應變 - 臨場發揮
- 拿紙出來用力畫啊
樹的定義
有各種版本
- 沒有環的連通圖。
- 沒有環,且加一條邊就會有環。
- 任兩個點都有唯一的簡單路徑。這通常是出題著要出樹的題目,不想直接寫。
樹的子樹區間
先看一個題目
例題
學姊日談
給你一棵樹,你要支援兩種操作
- add v x: 把一個點的權重加 x
- query v: 問一個點到根上所有點的權重和
第一個是樹的子樹區間,我們先看一個例題。
先觀察一下!
有些人可能一劈頭就樹鍊剖分下去,
先觀察可能有更簡潔的作法。說明這個題目就只是子樹
修改而已。
重點就是如何把一棵樹壓平
不只要把一棵樹序列化,還希望一個子樹就對應到一個區間。
把樹壓平
int time_stamp = 0;
void dfs(int u) {
start[u] = time_stamp;
for (v: adj[u]) {
dfs(v);
}
end[u] = ++time_stamp;
}
這邊就直接說結論,只要在 DFS 時把進入/離開節點的時間
記下來,就是一個合理的區間序列!
帶過一次 Code,說明區間是開的。
Example
這邊用閉區間,可以用開區間畫過一次。
樹分治
例題
Tree -
男人八題給一棵樹,樹的邊有權重表示距離,求距離不超過 \( k \) 的點對數。
\( \abs{V} \leq 10^4 \)
- 先講解一下題目。
- 這種跟路徑有關的問題通常有兩種做法,
一種是直接枚舉兩個端點。TLE。
一種是枚舉 LCS (或說路徑上一點)。
- 先說一下這題枚舉 LCS 大致作法。
- 用普通分治解說一下複雜度,說明最大的子樹不能太大。
定理
樹的重心任一棵樹一定存在這麼樣的一個點,拔掉他以後所有的子樹大小都不超過 \( \ceil{V / 2} \)。
挑到各點距離和最小的點就是
int dfs(int v) {
int total = 0, biggest = 0;
for (u: adj[v]) {
int t = dfs(u);
biggest = max(biggest, t);
total += t;
}
biggest = max(biggest, V - total - 1);
return total + 1;
}
遞迴下去取 max ,別忘了最外面那一坨。
Time complexity
\[ T(n) = \sum T(n_i) + f(n) \]
\[ T(n) \approx f(n) \log n \]
注意這個結論不完全正確。
回到原來那一題
重點: 如何合併
基本上「樹分治」是一個架構,題目的重點在於怎麼合併
啟發式合併
樹分治要找重心,很煩。
在適當的條件下可以用啟發式合併,不用找重心,DFS 下去合併上來就好了。
畫圖說明一下什麼是 DFS 下去合併。
剛剛 D&C 要找重心,現在不用,直接拿根。
定理
啟發式合併如果在合併時,每次都把其它的合併到最大的,
複雜度是 \( T(n) = (n \log n) g(n) \)。
關鍵還是在合併
g(n) 是把一個小的元素丟到大的所花時間。
例題
中位數你要維護兩種操作
-
query i : 問第 \( i \) 個 set 的中位數。
-
merge i j : 把第 \( j \) 個 set 裡的所有元素丟到 \( i \) 裡。
當然可以用一些很厲害的 DS 如 treap 做到。
樹鍊剖分
例題
QTREE -
SPOJ給你一棵樹,你要支援兩種操作
-
change e v : 把某個邊的權重改成 \( v \)
-
query a b : 問 \( a \) 到 \( b \) 的路徑上權重最大的邊。
把所有樹上的邊分成輕/重鍊。
- 每個點往他最大子樹連的邊是重邊。
- 每個點往他最大子樹連的邊是輕邊。
要注意不是最深的子樹。
定理
路徑上最多經過 \( \ord{\log \abs{V}} \) 條輕邊。
Link-cut tree
把重邊用 Splay tree, treap 等等可以 split 的資料結構維護。
可以拔邊
平面圖的定義
存在一個畫在平面的方法使得任兩條邊至多只在頂點相交。
比如正八面體是平面圖。但 \( K_{3, 3} \) 不是。
- 畫正八面體,不是立體的嗎?
- 所有多面體都是平面圖,投影。
- K33 常見的題目,井接水管。
例題
平面圖的最大團給你一個平面圖,求他最大團的大小。 \( \abs{V} \leq 2 \cdot 10^5 \)
在解這題之前,我們先看一些平面圖的性質最大團就是最大的一個完全子圖。
性質一: 邊很少
定理
歐拉定理對一個平面圖,\( \abs{E} = \abs{V} + \abs{F} - 2 \)
定理
對一個平面圖
- \( \abs{E} \leq 3\abs{V} - 6 \)
- 一定有一個點的度數不超過 \( 5 \)
- 說明「面」
- 證明 th2, 3F < 2E。
- 平均概念說明 th3.
每次都找度數最小的那個點。
枚舉完這個點就拔掉。
拔了這個點之後還是一個平面圖。
如果一個點度數少,可以直接枚舉他的鄰居。
性質二: Forbidden Graph
定理
平面圖的 Forbidden graph平面圖沒有 \( K_5 \) 和 \( K_{3,3} \)。
- K5 證明 => 歐拉。
- K3,3 證明 => 沒有 3 環。
有沒有可能無解?
一定有環?
- 無解 => 最無聊的情況, 1 > 2 > 3
- 若無環 => 總有最大的 (SCC)
- 有環 => 3 環。
二分圖的定義
可以分成兩團 \( A, B \) 的圖。同在一團的兩個點 \( u, v \) 沒有邊。
也可以說是能黑白染色的圖。
判斷一個圖是不是二分圖
黑白染色。
例題
平面圖的最大團現在有一個未知的序列 \( a_1, a_2, \dots, a_n \),依序給你資訊 \( (s, t, p) \),
其中 \( p \in {0, 1} \) 代表 \( a_s + a_{s+1} + \dots + a_t \equiv p \pmod{2} \),每次你要判斷給你的資訊會不會和已知的資訊有所矛盾,並且如果有矛盾則捨棄之。
先說明題意,並舉個矛盾的例子。
令 \( b_i = \sum a_i \) ,題目等於跟你講 \( b_i, b_j \) 是否同奇偶。
你跟我一樣 \( \implies \) 併查集
不一樣呢?
- 做前綴和。 sum(a_i) = b_j - b_i
- 先考慮同奇偶。
- 不同奇偶,多一個點。
Complexity classes
我們都希望所有問題都可以在 Polynomial time 完成。
事與願違,有些問題一直找不到多項式演算法,又證不了不存在。
假設我們有個超強的電腦。
Nondeterministic Turing machine
幸運值 Max, 永遠選到最快到終點的一條搜索路徑。
普通電腦多項式可以解的就叫 P, Nondeterministic Turing
machine 可以在多項式解的就叫 NP
NP = P ?
NPC
NP 裡最難的一些問題就叫做 NPC
如果這些問題在 P ,所有 NP 問題都在 P, P = NP
可以畫 P NP NPC NP-Hard GI BQP
Cook-Levin Theorem
定理
Cook-Levin TheoremSAT \( \in \) NPC。
例題
經典問題
證明
- 3-SAT \( \in \) NPC
- 3-color \( \in \) NPC
2-SAT
給你一個像以下的式子
\[ (x_1 \lor \lnot x_2) \land (\lnot x_3 \lor \lnot x_1) \land (x_{4} \lor x_{3}) \]
是否有一種變數的 assign 方法使得這個式子結果為true?比如 x_1, not x_3, x_4
說明一下符號,U = 多 倒U = 少
布林恆等式
\[ A \lor B \iff \lnot A \rightarrow B \iff \lnot B \rightarrow A \]
\[ A \to B, B \to C \quad \vdash \quad A \to C \]
先說一下布林恆等式。- -> = 則
- A or B = 沒有 A 一定要 B ,舉個例子說明。
定理
2-SAT 的有解條件2-SAT 有解若且唯若這些式子是一致的。
- 一致就是不會自相矛盾
- A -> not A 慘
- 舉一下剛剛的例子。
建模
\( x_1 \lor x_2 \)
\( x_1 \lor x_1 \)
or x1 = x1 ,用恆等式解釋。也就是這些 \( \square \to \square \) 不能讓 \( x_i, \lnot x_i \)在同一個環
SCC,用 tarjan 等等演算法 \( \ord{n} \)
不知道 SCC 的叫他回去(誤)
例題
給你一個 \( R \times C \) 的方格,你有一種特殊的炮彈可以炸一排或一列,
不過同一排或一列最多只能炸一次。每一格除了可能是空地外,還有可能是
- 敵方要塞,你必須炸兩次才能消滅他。
- 敵方軍團,你必須炸一次以上才能消滅。
- 住宅區,為了必免無辜的人受害,最多只能炸一次。
- 醫院,這個不用說,當然是炸都不能炸。
問你每一排及每一列該選擇炸或是不炸,才能使每一格都符合上述的需求? \( \ord{R+C+N} \)
怎麼轉成 2-SAT
- x_i or x_i
- x_i or x_j
- not x_i or not x_j
- not x_i or not x_i
3-SAT
雖然只差一點,但是個 NP 問題。
現在可以解到幾萬。Coloring
- 點塗色:把每個點塗一個顏色,使得任兩個相鄰的點都不同色。
- 邊塗色:把每個邊塗一個顏色, 使得一個點出去的邊都不同色。
都是 NPC Problem
點著色
例題
K Graph Oddity -
uva 4488給你一個連通圖 \( G \) 滿足 \( G \) 有奇數個點,且存在一個奇數\( k \) 使得所有點的度數都
不超過 \( k \)。請你把這張圖點 \( k \) 著色。 \( \abs{V} \leq 9999, \abs{E} \leq 10^5 \)
- deg k 的圖一定可以用 k+1 個顏色塗。
- 幾乎已經對了,可能是完全圖嗎?
- 跟平面圖那題很像!
邊著色
定理
Vizing's theorem任意一個簡單圖的邊著色數一定是 \( d, d+1 \) 中的一個,
其中 \( d = \max\limits_{v \in V} \deg(v) \)。
- deg k 的圖一定可以用 k+1 個顏色塗。
- 邊就沒有那麼顯然了。
- 概念複雜,我們用下面這個題目介紹。
例題
Edge coloring of bipartite graph -
Codeforces 600F給你一個二分圖,用最小的顏色將他邊著色。 \( \abs{V} \leq 2000, \abs{E} \leq 10^5 \)
答案是 \( d \).
一個邊一個邊加上去。
- 如果兩個人有共同缺的顏色 -> easy.
- 如果沒有 設 x, y 塗 x
- 另一個點出去 x 邊改 y
- 另一個點出去 y 邊改 x ...
- 只會回到原來的點 or 可以塗。
有解的條件
觀察一個路徑 \( v_1 \to v_2 \to \cdots \to v_n \)
每一個中間走到的點 \( +2 \) ,兩端 \( +1 \)。
度數奇偶是關鍵
定理
Euler Path 的存在條件定義一個 奇點 是度數為奇數的點。如果圖連通,有
- 一個無向圖有歐拉路徑的條件是其奇點的個數是 \( 0 \) 或 \( 2 \)。
- 一個無向圖有歐拉迴路的條件是其奇點的個數是 \( 0 \)。
- 一個有向圖有歐拉路徑的條件是所有點都滿足 \( \deg^+(v) = \deg^-(v) \),
或是除此之外有一個點滿足 \( \deg^+(v) = \deg^-(v) + 1 \),
另一個滿足 \( \deg^+(v) = \deg^-(v) - 1 \)。
- 一個有向圖有歐拉迴路的條件是所有點都滿足 \( \deg^+(v) = \deg^-(v) \),
Algorithm
vector<int> ans;
void dfs(int v) {
for (e: adj[v]) {
if (not e.visit) {
dfs(e.dest);
}
}
ans.push_back(v);
}
例題
POI 某題給你一個圖,每個邊都有 \( 0, 1 \) 的值,你走過一個邊就會讓
\( 0, 1 \) 互換,給你各個邊的起始值和目標值,問你存不存在這
樣子的一個走法。
Hamiltonian path
一條路徑走過所有的點恰好一次。
NPC Problem。
通常的做法是狀態壓縮 DP, \( \ord{2^n n^2} \)
Matching
幫每個點做配對,一個點只能配一次。
也可以想成是一些不相交的邊集。
二分圖上的匹配問題。
可以轉成 Flow 來解。
也可以用交錯路徑來想。
Flow 我們在接下來的課程會再題
一個匹配是最大匹配若且為若他沒有交錯路徑。
講一下交錯樹。
一般圖匹配
交錯路徑上會有奇環
縮花,非常複雜。
畫一下。
帶權完美匹配
二分圖可以轉成 Cost flow。
一般圖可以先找一個完美匹配在找負環。
或著點數小的時候可以狀態壓縮 DP。
例題
中國郵差問題給你一個圖,邊上有權重代表路徑長,你要找一個路徑,
經過所有的邊至少一次(可以重複走),最後回到出發點,問最短的路徑長。
很像 Euler cycle。
- 把他補成沒有奇點。
- 一次補兩個點。補外面的點不會比較好。
- 用最短路來補。
- Matching
一些相關的問題
- 最大獨立點集:一個最大的點集 \( V' \) 使得裡面的點都不相鄰。其大小記做 \( I(G) \)。
- 最大匹配數:前面定義過了。其大小記做 \( M(G) \)。
- 最小點覆蓋:最小的一個點集,使得所有的邊都至少與點集裡的一個點相鄰。其大小記做 \( C_v(G) \)。
- 最小邊覆蓋:最小的一個邊集,使得所有的點都至少與邊集裡的
一個邊相鄰。其大小記做 \( C_e(G) \)。
定理
- \( I(G) + C_v(G) = \abs{V} \).
- \( M(G) + C_e(G) = \abs{V} \).
- 對連通二分圖,有 \( M(G) = C_v(G), I(G) = C_e(G) \).
- 點覆蓋的補集就是獨立點集。
- 先找一個最大匹配,補成邊覆蓋。 M + M + V - 2M = V
例題
Tower Defense Game -
POI XX給你一張圖 \( G \) ,一個 \( d \)-covering 是一個 \(V(G)\) 的子集 \( U \) 使得
對於所有原圖上的點,一定有一個在 \( U \) 中的點使得這兩個點的距離不超過 \( d \)。
現在以知這個圖存在一個大小不超過 \( k \) 的 \(1\)-covering,請找出一個大小
不超過 \(k\) 的 \(2\)-covering。 \( \abs{V} \leq 5 \cdot 10^5, \abs{E} \leq 10^6 \)
亂做都行!
例題
經典問題問 \( n \) 個有編號的點可以形成多少種不同的樹。
例題
Connect Graph -
POJ 1737問 \( n \) 個有編號的點可以形成多少種不同的連通圖。
- 用扣的
- 慢慢 DP
- 第一個點的連通塊
- A[n] = 2^C(E, 2) - sum A[k] C(v, k-1) 2^C(v-k-1, 2)
例題
經典問題在一個完全圖上,所有的邊被塗上黑、白兩種顏色,問你有多少個同色三角形。
\( \abs{V} \leq 5000 \)
Problem description
example
Maximize \( x_1 - 2 x_2 + x_3 \)
Subject to
\[ \begin{align}
x_1 + x_2 - x_3 & \leq 7 \\
-x_1 - x_2 + x_3 & \leq -7 \\
x_1 - 2 x_2 + 2 x_3 & \leq 4 \\
x_1, x_2, x_3 & \geq 0 \\
\end{align} \]
Problem description
Maximize \( \mathbf{c} \cdot \mathbf{x} \)
Subject to \[ \mathbf{A} \mathbf{x} \leq b, \; \mathbf{x} \geq \mathbf{0} \]
Example - s-t shortest path
Min \( d_t \)
Subject to
\[ \begin{align}
d_v & \leq d_u + w(u, v) \\
d_s & = 0 \\
\end{align} \]
Dual Problem
Maximize \( \mathbf{c} \cdot \mathbf{x} \)
Subject to \[ \mathbf{A} \mathbf{x} \leq b, \; \mathbf{x} \geq \mathbf{0} \]
Minimize \( \mathbf{b} \cdot \mathbf{y} \)
Subject to \[ \mathbf{A}^T \mathbf{y} \leq c, \; \mathbf{x} \geq \mathbf{0} \]
\[ \mathbf{c} \cdot \mathbf{x} = \mathbf{b} \cdot \mathbf{y} \]
Example - Dual problem of weighted matching
Simplex
A non-polynomial algorithm to solve linear programming.
Slack form
Maximize \( 3x_1 + x_2 + 2x_3 \)
Subject to
\[ \begin{align}
x_1 + x_2 + 3x_3 & \leq 30 \\
2x_1 + 2x_2 + 5x_3 & \leq 24 \\
4x_1 + x_2 + 2 x_3 & \leq 36 \\
x_1, x_2, x_3 & \geq 0 \\
\end{align} \]
Slack form
Maximize \( 3x_1 + x_2 + 2x_3 \)
Subject to
\[ \begin{align}
30 - x_1 - x_2 - 3x_3 & = x_4 \\
24 - 2x_1 - 2x_2 - 5x_3 & = x_5 \\
36 - 4x_1 - x_2 - 2 x_3 & = x_6 \\
x_1, x_2, x_3, x_4, x_5, x_6 & \geq 0 \\
\end{align} \]
Maximize \( 3x_1 + x_2 + 2x_3 \)
Subject to
\[ \begin{align}
30 - x_1 - x_2 - 3x_3 & = x_4 \\
24 - 2x_1 - 2x_2 - 5x_3 & = x_5 \\
36 - 4x_1 - x_2 - 2 x_3 & = x_6 \\
\end{align} \]
Let us increase \( x_1 \). How much can we?
結論
- 這個 form 被 \( n \) 個變數決定。
- 當 \( \mathbf{c} \) 每個分量都小於 \( 0 \),就是
最佳解
- 此時的 \( \mathbf{c} \) 是 dual problem 的答案。
進階圖論Created by Meteor