1. 程式人生 > 其它 >[學習筆記] 二分圖判定

[學習筆記] 二分圖判定

定義

先看一下什麼是二分圖:

可以發現,這個圖被分成了兩個集合,每個集合之間的點都沒有邊相連,每條邊都是在兩個集合的點之間

判定

知道了定義後我們需要知道如何去判定一個圖,它是不是二分圖

我們一般會使用染色法

首先我們需要知道二分圖的一個性質:

二分圖不存在長度為奇數的環

因為每條邊都是從一個集合到另一個集合,如果要回到一個集合那隻能走偶數次

這種方法是把所有的點分成兩種顏色(對應兩種集合),如果這張圖是二分圖,那麼每條邊連線的兩個點的顏色

都應該是不同的

所以我們從第一個點開始,把它染成\(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都會把連通的一整部分搜完,當然也不可能搜到之前的點啦

其實染色法判斷的就是:同一集合有沒有邊相連