0x00 图着色问题

图着色问题(Graph Coloring Problem, GCP)又称着色问题,是最著名的NP-完全问题之一。

  • 图的m可着色判定问题

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

  • 图的m可着色优化问题

若一个图最少需要m种颜色才能使图中每条边连接的2个顶点着不同颜色,则称这个数m为该图的色数。

0x01 图的m可着色判定问题

判定问题采用暴力dfs处理,对于当前的节点cur,其前面的节点已经着色过了,判断cur节点可以使用的颜色即可。如何判断cur节点可以使用的颜色呢?遍历所有颜色,判断当前颜色icur周围节点的颜色是不是不一样,如果是的话,那么可行;否则,不可行。

#include <iostream>
#include <cstring>
using namespace std;const int N = 100, M = N * 2;
struct Edge {int to, next;
} edge[M];int head[N], color[N], idx = -1;
int n, m, k;// n表示节点个数, m表示颜色个数,k表示数据个数
bool res = false;void add(int u, int v) {edge[++idx].to = v;edge[idx].next = head[u];head[u] = idx;
}//判断位置cur是否可以放入颜色i
bool check(int cur, int i) {for (int j = head[cur]; ~j; j = edge[j].next) {int son = edge[j].to;if (color[son] == i) return false;}return true;
}void dfs(int cur) { //cur从0开始计算if (cur >= n) {res = true;return;}for (int i = 1; i <= m; i++) {if (check(cur, i)) {color[cur] = i;dfs(cur + 1);}}
}

另外上述代码稍加修改就可以计算方案个数。

#include <iostream>
#include <cstring>
using namespace std;const int N = 100, M = N * 2;
struct Edge {int to, next;
} edge[M];int head[N], color[N], idx = -1;
int n, m, k;
int res;void add(int u, int v) {edge[++idx].to = v;edge[idx].next = head[u];head[u] = idx;
}bool check(int cur, int i) {for (int j = head[cur]; ~j; j = edge[j].next) {int son = edge[j].to;if (color[son] == i) return false;}return true;
}void dfs(int cur) {if (cur >= n) {res++;return;}for (int i = 1; i <= m; i++) {if (check(cur, i)) {color[cur] = i;dfs(cur + 1);color[cur] = 0;}}
}

0x02 图的m可着色优化问题

我在论坛上看到如下问题

元素=[1,2,3,4,5,6,7,8,9] 互斥=[(1,4),(2,5),(1,5),(5,6),(7,8),(3,9),(2,8),(4,5)]
把元素组成 N 个组, 保证互斥元素不在同一个组里, 并且 N 最小

这个问题实际上就是图的m可着色优化问题。

图的m可着色优化问题首先不难想到通过二分法(加上0x01中的方法)来做,但是这么做的话时间复杂度过高。可以直接采用dfs来处理。(为了处理简单,使用矩阵存储图)

每次判断当前数cur能不能放入之前的集合中,如果不能放入,那么新开辟一个集合;否则,放入即可。那么关键问题就是判定能否放入之前的集合中?将集合中的每个数存储,然后判断当前数cur和这些数是不是互斥即可。

#include <iostream>
#include <cstring>
using namespace std;const int N = 100;
int cnt[N], num[N][N], g[N][N];//cnt表示每个集合中元素个数,num表示第i个集合中的第j个元素是谁,g表示关系图。
int n, k;// n表示节点个数,k表示数据个数
int res;//判断第i个集合是不是可以放入cur(也就是i中的元素都不和cur互斥)
bool check(int cur, int i) {for (int j = cnt[i]; j > 0; --j) {if (g[num[i][j]][cur]) return false;}return true;
}//将cur放入第s个集合中
void dfs(int cur, int s) { //cur从1开始计算if (s >= res) return;if (cur > n) {res = s;return ;}for (int i = 1; i <= s; i++) { if (check(cur, i)) {num[i][++cnt[i]] = cur;dfs(cur + 1, s);num[i][cnt[i]--] = 0;}}s++;num[s][++cnt[s]] = cur;dfs(cur + 1, s);num[s][cnt[s]--] = 0;
}

reference:

https://baike.baidu.com/item/%E5%9B%BE%E7%9D%80%E8%89%B2%E9%97%AE%E9%A2%98/8928655?fr=aladdin

https://www.cnblogs.com/czsharecode/p/10558732.html

如有问题,希望大家指出!!!

图着色问题(超详细!!!)相关推荐

  1. CDN+COS搭建图床超详细步骤

    CDN+COS搭建图床超详细步骤 一.前言 二.准备工作 1. 域名 2. DNS解析 三.原理解析 四.COS部署 1. 创建存储桶 2.创建文件夹 五.CDN部署 1.基础配置 2.源站配置 3. ...

  2. 考研高等数学上下册归纳总结思维脑图(超详细)

    数二思维脑图有需要的考研同学可以看一下!超详细,看完之后,高数的体系结构一清二楚!在这只上传一张图,详细内容可到我的网盘中下载查看! 链接:https://pan.baidu.com/s/1etNSe ...

  3. pcapy安装教程(多图,超详细)

    前段时间一直在研究OpenRCE的sulley框架,在艰难安装过程也顺便安装了pcapy,突然发现网上对pcapy的解释说明不是很全,所以在此整理和详细说明一下pcapy的安装过程,希望能帮助大家!测 ...

  4. 【数据结构知识】图【超详细版】

    前言 这一章内容比较多,每一节的知识点都很复杂,需要花很长时间才能搞懂,希望看的人耐心一点. [数据结构系列][前一章:树][后一章:查找] 六.图 目录 六.图 1.图的顶点和边间的关系 2.连通图 ...

  5. 微软AI 绘图工具+ChatGPT免费用,10秒轻松出图,超详细教程,纯干货分享

    文 / 高扬(微信公众号:量子论) 人嘛,总爱喜新厌旧.很多朋友找我(gaoyang677)建议将"量子论"公众号的教程再做个扩展,比如讲讲如何用AI绘图. 经过内部讨论,认为这个 ...

  6. 模糊测试工具Sulley开发指南(1)——安装Sulley(多图,超详细)

    本教程是针对的是windows上面的安装,至于其他系统的安装有时间的话会贴出来,本教程翻译自OpenRCE/Sulley-GitHub-Wiki官网教程,但是里面有一些错误我会更正指出.值得一提是,我 ...

  7. 使用ComplexHeatmap绘制复杂热图|Note2:单个热图(万字超详细教程)

    2. 单个热图 2.1 颜色 2.2 标题 2.3 聚类 2.3.1 距离方法 2.3.2 聚类方法 2.3.3 渲染树状图 2.3.4 重排树状图 2.4 设置行列顺序 2.5 维度名称 2.6 热 ...

  8. Redis的,思维导图「超详细」

    通过思维导图整理的Redis的重要知识点 一.持久化 二.复制 三.阻塞 四.Redis内存 五.Redis内存优化 六.哨兵 七.缓存设计

  9. 8张JS 基础思维图,超详细!

    大家好,我是漫步,之前我分享过8张JS思维图.面试思维图,今天再次分享八张JS基础的思维图,希望对你有所帮助. 1. javascript变量 2. javascript运算符 3. javascri ...

  10. NN-Descent构建K近邻图——论文超详细注解

    个人博客:www.mzwang.top 论文题目 Efficient K-Nearest Neighbor Graph Construction for Generic Similarity Meas ...

最新文章

  1. java dagger2_java – Dagger2不生成Daggercomponent类
  2. 【ijkplayer】编译 Android 版本的 ijkplayer ② ( 切换到 k0.8.8 分支 | 执行 init-android.sh 脚本进行初始化操作 )
  3. Community Server系列之四:Ajax在CS2.0中的应用1
  4. 作用域、执行环境、闭包(四)
  5. 2012-13学年上半学期路由与交换课程设计-作业-2
  6. 蓝屏修复工具和蓝屏代码查询软件
  7. Apache Tomcat选择哪个版本好?
  8. u盘linux系统 隐藏文件,轻松显示U盘隐藏的文件夹绝招
  9. MybatisPlus实现数据库加解密
  10. 解决 :No active profile set, falling back to default profiles: default 问题
  11. 新个税计算html、以及java源代码
  12. python123第四周_百度杯十月第四周WriteUp
  13. 目标跟踪数据集GOT-10k的配置
  14. 对计算机专业学生的忠告
  15. 创业思维的误区 (余世维)
  16. electron_笔记
  17. Python中for循环的使用
  18. 腾讯推页游平台’”页游乐园”YY.QQ.com
  19. 记录第一次纯手打爬虫经历
  20. 最TOP小程序排行榜出炉

热门文章

  1. ftp服务器软件,推荐几款免费的ftp服务器软件,ftp客户端下载
  2. Vue.js实战:初识Vue.js
  3. Cobuyor持续回报模式在电子商务支付交易体系中的地位和趋势
  4. python图片自动上色_自己实现黑白图片自动上色AI(一)
  5. 杂记——贝叶斯可信区间与频率置信区间的区别
  6. Qt实现类似QQ头像
  7. 关于chm电子书无法显示网页的解决方
  8. 中国人霸屏奥运会乒乓球赛这事 外国人怎么看?
  9. 解决steamcommunity报错443/80端口被占用
  10. 刘备是怎样“融资”创业的?