图的搜索

二分图判定:给定一个具有n个顶点的图。要给图上每个顶点染色,并且要使相邻的顶点颜色不同。问是否能最多用2中颜色进行染色?题目保证没有重边和自环。 (1<=n<=1000)

      把相邻的顶点染成不同的颜色叫做图着色问题。对图进行着色所需要的最小颜色数称为最小着色数。最小着色数为2的图称为二分图。

如果只用2种颜色,那么确定一个顶点的颜色之后,和它相邻的顶点的颜色也就确定了。因此,选择任意一个顶点出发,依次确定相邻顶点的颜色,就可以判断是否可以被2种颜色染色了。这个问题如果用深度优先搜索的话,能够简单的实现。

vector <int> G[MAX_V];	//图
int V;	//顶点数

int color[MAX_V];	//顶点i的颜色(1 or -1)

//把顶点染成1或-1
bool dfs(int v, int c) {
	color[v] = c;		//把顶点v染成颜色c
	for (int i = 0; i<G[v].size(); i++) {
		//如果相邻的顶点同色,则返回false 
		if (G[v][i] == c)	return false;
		//如果相邻的顶点还没被染色,则染成-c
		if (color[G[v][i]] == 0 && !dfs(G[v][i], -c)) 	return false;
	} 
	return true;
} 

void solve() {
	for (int i = 0; i<V; i++) {
		if (color[i] == 0) {
			//如果顶点i还没被染色,则染成1
			if (!dfs(i, 1)) {
				cout << "NO" <<endl;
				return ; 
			} 
		}
	}
	cout << "YES" << endl;
}

如果是连通图,那么一次dfs就可以访问到所有的顶点。如果题目描述中没有说明,那么有可能图是不连通的,这样就需要依次检查每个顶点是否访问过,判断图是否是一个连通图或者是否是一棵树,都只需将dfs进行一些修改就可以了。通过dfs也可以求图的拓扑序。由于每个顶点和每条边都只访问了一次,因此复杂度是O(|V| + |E|)。

原文地址:https://www.cnblogs.com/Tovi/p/6194816.html