图的m着色问题----回溯法解决

关于什么按顶点的度排序、题目具体要求和细节请参考我男神的博客

#include <iostream>
#include <algorithm>
#include <iomanip>
using  namespace std;
int information[2][22] = {{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7}, {2, 6, 7, 1, 7, 3, 2, 7, 4, 6, 3, 5, 6, 4, 5, 4, 7, 1, 6, 1, 2, 3}};
const int number = 22;
class Point{
public:
    int index;//存顶点编号
    int number;//存该顶点的边
};
bool cmp(Point &p1, Point& p2)//将顶点按照顶点的度排序,加快运算速度
{
    return p1.number > p2.number;
}
class Color{
private:
       int **_line_array;//邻接矩阵
    int _point_number;//点的个数
    int _color_number;//颜色个数
    int *_solution;//解
    Point* _points_order;//更新点的顺序
    vector<int*> _solutions;//所有解的矩阵
public:
    Color(int point_number, int color_number):_point_number(point_number), _color_number(color_number)
    {
        //初始化数据
        _line_array = new int*[_point_number];
        _points_order =new Point[_point_number];
        _solution = new int[_point_number];
        for(int i = 0; i < _point_number; i++)
        {
            _line_array[i] = new int[_point_number];
            for(int j = 0; j < _point_number; j++)
                _line_array[i][j] = 0;
            _points_order[i].index = i;
        }
        for(int i = 0; i < number; i++)
        {
           _line_array[information[0][i] - 1][information[1][i] - 1] = 1;
        }
        for(int i = 0; i < _point_number; i++)
        {
            int sum = 0;
            for (int j = 0; j < _point_number; j++)
            {
                if(_line_array[i][j] == 1)
                    sum++;
            }
            _points_order[i].number = sum;
        }
        sort(_points_order, _points_order + _point_number, cmp);
        Backtrack(0);
        Print();
    }
    bool OK(int t)//判断该顶点取某种颜色时是否与之前的冲突
    {
        for(int i = 0; i < t; i++)
        {
            if(_line_array[_points_order[i].index][_points_order[t].index] == 1)
                if(_solution[i] == _solution[t])
                    return false;
        }
        return true;
    }
    void Backtrack(int t)//回溯
    {
        if(t >= _point_number)//找到解时存起来
        {
            int *x;
            x = new int[_point_number];
            for(int i = 0; i < _point_number; i++)
            {
                x[_points_order[i].index] = _solution[i];
            }
            _solutions.push_back(x);
            return;
        }
        for(int i = 0; i < _color_number; i++)//递归
        {
            _solution[t] = i;
            if(OK(t))//判断是否满足约束函数
                Backtrack(t + 1);
        }
    }
    void Print()//输出全部的解
    {
        cout << "共有 " << _solutions.size() << " 种方案"<< endl;
        if(_solutions.size() == 0)
            cout << "无法取得结果" << endl;
        else
            for(int i = 0; i < _solutions.size(); i++)
            {
                cout << "顶点:";
                for(int  j = 0; j < _point_number; j++)
                    cout<<setiosflags(ios::right) << setw(3) << j + 1;
                cout << endl;
                cout << "颜色:";
                for(int j = 0; j < _point_number; j++)
                {
                    cout<<setiosflags(ios::right) << setw(3) << _solutions[i][j] + 1;
                }
                cout << endl << endl;
            }
    }
    ~Color()
    {
        for(int i = 0; i < _point_number; i++)
            delete []_line_array[i];
        delete []_line_array;
        delete []_solution;
        _solutions.clear();
        delete []_points_order;
    }
};
int main()
{
    Color color(7, 3);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值