Description
输入一个简单(无多重边和自环)的连通无向图,判断该图是否能用黑白两种颜色对顶点染色,使得每条边的两个端点为不同颜色。
Input
输入的第一行包含两个整数n和m,n是图的顶点数,m是边数。1<=n<=1000,0<=m<=10000。
以下m行,每行是一个数对u v,表示存在边(u,v)。顶点编号从1开始。
Output
如果能做到双着色,输出"yes",否则输出"no"。
解题思路:使用深度搜索解决
#include <iostream>
#include <string.h>
#define MAX 1005
using namespace std;
int graph[MAX][MAX]; // 表示边的矩阵
bool visited[MAX]; //表示访问过的点
int colored[MAX]; //表示涂色情况
bool DFS(int point, int start){
for (int i = 1; i <= point; i ++) {
if (graph[start][i] == 1 && visited[i] == false) {
visited[start] = true;
if (colored[start] == 1) { // start点已经涂了1号色
if (colored[i] == 0) colored[i] = 2; // i点还没有涂色,让i点涂2号色
else if(colored[i] == 1)return false; // i点已经涂了跟start点一样的1号色,则表示不成功
}
else{ // start不是涂1号色
if (colored[i]== 0) colored[i] = 1; // i点还没涂色,将i点涂1号色
else if(colored[i] == 2)return false;
}
if(DFS(point, i) == false)return false;
}
}
return true;
}
int main(int argc, const char * argv[]) {
// insert code here...
int vertex,edges;
while (cin >> vertex) {
if (vertex == 0) break;
cin >> edges;
int u,v;
memset(graph, 0, sizeof(graph)); // 初始化所有信息
memset(visited, false, sizeof(visited));
memset(colored, 0, sizeof(colored));
if (edges == 0) break;
for (int i = 0; i < edges; i++) {
cin >> u >> v; // 输入边
graph[u][v] = 1;
graph[v][u] = 1;
}
if (DFS(vertex,1)) cout << "yes" << endl;
else cout << "no" << endl;
}
return 0;
}