[學習筆記] 二分圖判定
阿新 • • 發佈:2021-10-29
定義
先看一下什麼是二分圖:
可以發現,這個圖被分成了兩個集合,每個集合之間的點都沒有邊相連,每條邊都是在兩個集合的點之間
判定
知道了定義後我們需要知道如何去判定一個圖,它是不是二分圖
我們一般會使用染色法
首先我們需要知道二分圖的一個性質:
二分圖不存在長度為奇數的環
因為每條邊都是從一個集合到另一個集合,如果要回到一個集合那隻能走偶數次
這種方法是把所有的點分成兩種顏色(對應兩種集合),如果這張圖是二分圖,那麼每條邊連線的兩個點的顏色
都應該是不同的
所以我們從第一個點開始,把它染成\(1\),然後把和它相連的邊染成\(-1\)
如果我們要染色的點已經有了顏色並且和當前點的顏色是相同的,那麼這就不是二分圖
code
for(int i=1;i<=n;i++)
if(!c[i])
if(!dfs(i,1))
cout<<"NO"<<endl;
bool dfs(int u,int col){
c[u]=col;
for(int i=head[u];i;i=nxt[i]){
int v=ver[i];
if(!c[v]&&!dfs(v,-col)) return 0;
else if(c[v]==col) return 0;
}
return 1;
}
至於為什麼每個點都要dfs一下,因為二分圖可能不是連通的,以下為同一個圖:
\(Q\):每個點開始dfs的時候都染成\(1\),萬一開始染色點是和點\(1\)在不同集合怎麼辦?
可以手動模擬下一上圖,其實每次dfs都會把連通的一整部分搜完,當然也不可能搜到之前的點啦
其實染色法判斷的就是:同一集合有沒有邊相連