写得很精炼的一个图m着色算法,帮作者加了注释。 利用图的二着色,可以判断一个图是否为二分图。 #include <iostream> using namespace std; // 判断对顶点k着色以后是否合法着色 bool ok(int x[], int k, bool c[5][5], int n) { int i; for(i = 0; i < k; i++) if((c[k][i] && x[k] == x[i])) // 第k个顶点与某个相邻的顶点有颜色冲突 return false; return true; // 合法 } // 输入n为顶点个数,颜色数m,图的邻接矩阵c[][] // 输出n个顶点的着色x[] void m_coloring(int n, int m, int x[], bool c[5][5]) { int i, k; // 一开始各个顶点无颜色 for(i = 0; i < n; i++) x[i] = 0; k = 0; // 从第0个顶点开始着色 while(k >= 0) { x[k]++; while((x[k] <= m) && (!ok(x, k, c, n))) // 得到最高标值的颜色 x[k]++; if(x[k] <= m) // 第k个顶点的染色是合法的 { if(k == n - 1) // 所有的顶点都已经染完色,程序退出 break; else k++; // 继续下一个顶点的染色 } else // 第k个顶点的染色不合法,回溯 { x[k] = 0; k--; } } } // test int main() { // 初始化 bool c[5][5]; int x[5]; int i, j; for(i = 0; i < 5; i++) for(j = 0; j < 5; j++) c[i][j] = false; // 定义图 c[0][1] = true; c[0][2] = true; c[1][2] = true; c[1][3] = true; c[1][4] = true; c[3][4] = true; c[2][4] = true; c[1][0] = true; c[2][0] = true; c[2][1] = true; c[3][1] = true; c[4][1] = true; c[4][3] = true; c[4][2] = true; // 对5个顶点的图进行3着色 m_coloring(5, 3, x, c); // 输出颜色 for(i = 0; i < 5; i++) cout << x[i] << " "; cout << endl; return 0; }