Vizing 定理
圖染色問題的經典結論
圖染色定義
稱一個邊染色方案合法當且僅當每個頂點連出的所有邊的顏色都互不相同,如果此時出現了 \(k\) 個顏色那么稱該方案是圖的一組 \(k\) 染色
一張無向圖的邊着色數為最小的 \(k\) 滿足圖可以 \(k\) 邊染色,但不存在一個 \(k-1\) 邊染色方案,記圖 \(G\) 的邊色數為 \(\chi'(G)\)
同時記 \(\Delta(G)\) 為圖上的最大度數
\(\rm{Vizing}\) 定理:
-
如果滿足 \(G\) 是二分圖,那么 \(\chi'(G)=\Delta(G)\)
考慮對這部分進行構造性證明:
考慮向二分圖中加入邊 \((x,y)\),設 \(c_x\) 為 \(x\) 點連出的邊的顏色中的一個在 \([1,c]\) 中沒有出現的顏色,\(c_y\) 同理
如果 \(c_x=c_y\) 那么直接將這條邊染成 \(c_x\) 即可
否則不妨設 \(c_x< c_y\) 將 \(y\) 點連出的顏色為 \(c_x\) 的邊改成顏色 \(c_y\) 並將邊 \((x,y)\) 染成 \(c_x\)
同時由圖是二分圖,那么一定可以從 \(y\) 點開始找到一條終點不是 \(x\) 的增廣路,路徑顏色為 \(c_x,c_y\) 交替,直接在 \(\{c_x,c_y\}\) 集合內反色即可
-
如果 \(G\) 是簡單圖,那么 \(\Delta(G)\le \chi'(G)\le \Delta(G)+1\)
證明博主不會
例題
Undefined
一張 \((n,m)\) 點的二部圖,有 \(k\) 條邊,\(c\) 個顏色
一個點的代價是給其邊染色之后邊表中出現次數最多的顏色減去出現次數最少的顏色,求所有點的代價和的最小值
首先給出結論:\(\rm{Min}=n+m-\sum_{i=1}^{n+m}[c|deg[i]]\)
將一個點的 \(c\) 個邊包裝成一組進行建立新點,新圖仍然是二分圖,同時滿足每個點的度數 \(\leq c\)
直接使用 \(\rm{Vizing}\) 定理完成結論證明
UOJ44
和上面的題目類似,對於加邊操作,動態加虛點找增廣路
刪邊判一下是不是最后一個虛點,不是的話從最后一個點扒一個過來即可
Bron–Kerbosch 算法
求圖的最大團,也可以隨機化排列貪心加點,隨機化算法在n小的時候正確率一次能到 \(3\%\)
BK算法求最大團大小時簡單得離譜,直接放代碼
const int N=100;
int ans,num[N],sta[N],n,m;
double sum;
inline bool dfs(int now,int x,int res){
for(int i=x+1;i<=n;++i){
if(num[i]+res<=ans) break;
if((sta[i]&now)==now){
if(dfs(now|1ll<<(i-1),i,res+1)) return 1;
}
} if(res>ans) return ans=res,1; return 0;
}
signed main(){
n=read(); m=read(); sum=read();
for(int i=1;i<=m;++i){
int u=read(),v=read();
sta[u]|=1ll<<(v-1);
sta[v]|=1ll<<(u-1);
}
Down(i,n,1) dfs(1ll<<(i-1),i,1),num[i]=ans;
print(ans);
return 0;
}
注意代碼短小的同時意味着不能刪減任何細節,比如 $ dfs $ 必須有返回值來保證找到就退出
復雜度是 \(\Theta(3^{\frac n3})\),相比於折半再 \(\rm{DP}\) 的做法,空間優秀很多
復雜度的來源是一張圖的最大團上界為 \(\Theta(n^{\frac n3})\),比較復雜,論文完全看不懂
上面寫的內容是使用BK算法求解最大團的大小,相對復雜的是求解極大團的個數:
在 \(dfs\) 維護三個集合 \(R\):當前最大團集合,\(P\):當前可能加入最大團的集合,\(X\):對於當前 \(R\) 已經被計算過最大團的點的集合
每次找 \(P\) 中找一個和 \(R\) 中所有點相連的點 \(x\),\(R\leftarrow R\cup\{x\},P\leftarrow P\cap N(x),X\leftarrow X\cap N(x)\)
觀察到冗余的排除是兩個點被加入最大團的順序是無所謂的,那么對於每個 \(P\) 找到 集合度數\((N(u)\cap P)\) 最大的點作為中樞點,此時能選的點要不是自己,要不是和它不相連的點
對於相連的點,最后統計到包含自己但不包含中樞點的,必然會在不相鄰點處被統計;對於包含自己又包含中樞點的情況,在后續的 \(dfs\) 中會作為 \(P\) 中的點被選出來
初始化 \(P=U\) 當 \(P=X=\empty\) 時就找到了一個極大團