图着色算法描述:

https://www.jianshu.com/p/6a52b390f5fa

给定无向连通图和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的两个顶点有不同的颜色。

这个问题是图的m可着色判定问题。若一个图最少需要m种颜色才能使图中每条边相连接的两个顶点着不同颜色,称这个数m为这个图的色数。

求一个图的色数m称为图的m可着色优化问题。 给定一个图以及m种颜色,请计算出涂色方案数。


 
 

图的着色算法分析:

  1. Color存储着色方案。
  2. 从第一个顶点开始着色,判断是否安全。
  3. 安全则继续着色直到顶点全部被着色,输出可行的着色方案
  4. 若不安全则停止着色方案,回溯,测试下一方案

本人使用的是C#,以下是完整代码,输入为顶点数,颜色数和图的连接矩阵。IsSafe函数判断安全与否,ColorGraph函数具体着色。递归实现回溯。

using System;
namespace graphColoring
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入顶点数:");
            string numberN = Console.ReadLine();
            int N = Int32.Parse(numberN);

            Console.WriteLine("请输入颜色数:");
            string numberColor = Console.ReadLine();
            int M= Int32.Parse(numberColor);

            int[, ] matN = new int[N, N];           //无向图的邻接矩阵
            Console.WriteLine("请输入无向图的邻接矩阵:");
            for(int i = 0; i < N; i++)
            {
                string str = Console.ReadLine();
                string[] temp = str.Split(" ".ToCharArray());
                for(int j = 0; j < N; j++)
                {
                    matN[i, j] = Int32.Parse(temp[j]);
                }
            }
            int[,] MatN = matN;
            graph myGraph = new graph(N,M,MatN);
            Console.WriteLine("所有的方案:");
            myGraph.graphDeal();

        }
    }
    class graph
    {
        private int n;                           //顶点数
        private int m;                           //颜色数
        private int[,] matN;                     //邻接矩阵
        private int[] color;                     //着色方案
        public graph(int N,int M,int[,] MatN)
        {
            n = N;
            m = M;
            matN = MatN;
            color = new int[n];
            for (int i = 0; i < n; i++)
                color[i] = 0;
        }
        public void graphDeal()
        {
            ColorGraph(matN, m, color, 0);
        }
        private bool IsSafe(int[, ] matN,int[] color, int n1, int i)
        {
            for(int j = 0; j < n; j++)
                if (matN[n1, j] == 1 && i == color[j])
                    return false;
            return true;
        }
        private void ColorGraph(int[, ] matN,int m,int[] color,int n1)
        {
            if (n == n1)
            {
                printSolution(color);
                return;
            }
            for(int i = 1; i <= m; i++)
            {
                if (IsSafe(matN, color, n1, i))
                {
                    color[n1] = i;
                    ColorGraph(matN, m, color, n1 + 1);
                    color[n1] = 0;                           //如果缺少则color无法在每个正确或者错误的方案完成后重置
                }
            }
        }
        void printSolution(int[] color)
        {
            foreach(int i in color)
            {
                Console.Write(i+" ");
            }
            Console.WriteLine();
        }
    }
}
01-03 02:21