zoukankan      html  css  js  c++  java
  • 回溯法(四)——图的m着色问题

    1 题目描述

      给定无向连通图G=(V, E)m种不同的颜色,用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中相邻的两个顶点有不同的颜色?

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

      编程计算:给定图G=(V, E)m种不同的颜色,找出所有不同的着色法和着色总数。

    2 输入

      第一行是顶点的个数n(2≤n≤10),颜色数m(1≤m≤n);
      接下来是顶点之间的相互关系:a b,表示a和b相邻。当a,b同时为0时表示输入结束。

    3 输出

      输出所有的着色方案,表示某个顶点涂某种颜色号,每个数字的后面有一个空格。最后一行是着色方案总数。

    4 样例输入

    5 4
    1 3
    1 2
    1 4
    2 3
    2 4
    2 5
    3 4
    4 5
    0 0
    

    5 样例输出

    1 2 3 4 1 
    1 2 3 4 3 
    1 2 4 3 1 
    1 2 4 3 4 
    1 3 2 4 1 
    1 3 2 4 2 
    1 3 4 2 1 
    1 3 4 2 4 
    1 4 2 3 1 
    1 4 2 3 2 
    1 4 3 2 1 
    1 4 3 2 3 
    2 1 3 4 2 
    2 1 3 4 3 
    2 1 4 3 2 
    2 1 4 3 4 
    2 3 1 4 1 
    2 3 1 4 2 
    2 3 4 1 2 
    2 3 4 1 4 
    2 4 1 3 1 
    2 4 1 3 2 
    2 4 3 1 2 
    2 4 3 1 3 
    3 1 2 4 2 
    3 1 2 4 3 
    3 1 4 2 3 
    3 1 4 2 4 
    3 2 1 4 1 
    3 2 1 4 3 
    3 2 4 1 3 
    3 2 4 1 4 
    3 4 1 2 1 
    3 4 1 2 3 
    3 4 2 1 2 
    3 4 2 1 3 
    4 1 2 3 2 
    4 1 2 3 4 
    4 1 3 2 3 
    4 1 3 2 4 
    4 2 1 3 1 
    4 2 1 3 4 
    4 2 3 1 3 
    4 2 3 1 4 
    4 3 1 2 1 
    4 3 1 2 4 
    4 3 2 1 2 
    4 3 2 1 4 
    Total=48
    

    6 求解思路

      使用回溯法,具体步骤是将cur=1传入backtrack(),即从第一个开始涂色。

      涂的时候从颜色1开始到m,每当涂上一个色,要用ok(cur)判断第cur个点是否可以涂这个色,不可以的话就不再往下涂了,改试另一个颜色,可以的话就继续……执行完这个for循环就回溯。

      当cur>n的时候即前n个点都涂完了,然后输出结果并cou++计数。

    7 C++版本代码如下

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    int n, m;
    int a = 1, b = 1;
    int cou = 0;
    // 邻接矩阵
    int graph[20][20];
    // 着色表
    int color[20];
    
    // 判断是否可以着色
    bool ok(int c)
    {
        for(int k=1;k<=n;k++)
        {
            if(graph[c][k]&&color[c]==color[k])
            {
                return false;
            }
        }
        return true;
    }
    
    void backtrack(int cur)
    {
        if(cur>n)
        {
            for(int i=1;i<=n;i++)
            {
                printf("%d ",color[i]);
            }
            cou++;
            printf("
    ");
        }
        else
        {
            for(int i=1;i<=m;i++)
            {
                color[cur]=i;
                if(ok(cur))
                {
                    backtrack(cur+1);
                }
                color[cur]=0;
            }
        }
    }
    
    int main()
    {
        memset(graph, 0, sizeof(graph));
        memset(color, 0, sizeof(color));
        scanf("%d %d", &n, &m);
        while(scanf("%d %d", &a, &b) != EOF && a != 0 && b != 0)
        {
            graph[a][b] = 1;
            graph[b][a] = 1;
        }
        backtrack(1);
        printf("Total = %d", cou);
        return 0;
    }
    
  • 相关阅读:
    C. Shaass and Lights 解析(思維、組合)
    D. Binary String To Subsequences(队列)(贪心)
    CodeForces 1384B2. Koa and the Beach (Hard Version)(贪心)
    CodeForces 1384B1. Koa and the Beach (Easy Version)(搜索)
    CodeForces 1384C. String Transformation 1(贪心)(并查集)
    CodeForces 1384A. Common Prefixes
    POJ-2516 Minimum Cost(最小费用最大流)
    POJ3261-Milk Patterns(后缀数组)
    HDU-1300 Pearls(斜率DP)
    HDU-4528 小明系列故事-捉迷藏(BFS)
  • 原文地址:https://www.cnblogs.com/flyingrun/p/13489952.html
Copyright © 2011-2022 走看看