二分图判定
对于无向图$G=(V,E)$,如果可以把节点集分成不相交的两部分,即$X$和$Y=V - X$,使得每条边边的其中一个端点在$X$中,另一个端点在$Y$中,则称图$G$是二分图(bipartite graph)。二分图的另一个等价说法是,可以把每个结点着以黑色和白色之一,使得每条边的两个端点颜色不同。不难发现,非连通的图是二分图当且仅当每个连通分量是二分图,因此我们只考虑无向连通图。容易看出,无环连通图一定是二分图。下面给出判断结点$u$所在的连通分量是否是二分图的代码:
1 int color[maxn]; 2 bool dfs(int u){ 3 FOR(i, 0, G[u].size() - 1){ 4 int v = G[u][i]; 5 if(color[v] == color[u]) return 0; 6 if(!color[v]){ 7 color[v] = 3 - color[u]; 8 if(!dfs(v)) return 0; 9 } 10 } 11 return 1; 12 } 13 bool bipartite(int u){ 14 clr(color, 0); 15 color[u] = 1; 16 return dfs(u); 17 }
原理很简单,就是把$u$结点的颜色置为$1$,以其为跟扩展出一棵dfs树,当且仅当所有结点对颜色不冲突时无向图为二分图。