回溯法-图的m着色问题

news2024/11/24 13:07:32

图的 m 着色问题

问题描述

给定一个无向连通图 ( G = (V, E) ) 和 ( m ) 种颜色,我们的任务是为图 ( G ) 的每个顶点着色,使得相邻的顶点颜色不同。如果存在这样的着色方案,我们称之为图 ( G ) 的 ( m ) 可着色问题。

算法思路

  1. 初始化:创建一个二维数组 colors 来记录每个顶点的颜色。
  2. 选择起始点:从图中任选一个顶点作为起始点,并为其着色。
  3. 相邻顶点着色:对于起始点相邻的顶点,依次尝试着色,确保相邻顶点颜色不同。
  4. 回溯:如果某个顶点无法着色,则回溯到上一个顶点,尝试其他颜色。
  5. 完成着色:当所有顶点都被成功着色时,记录着色方案。

算法设计

输入

  • 图 ( G = (V, E) ),其中 ( V ) 是顶点集合,( E ) 是边集合。
  • 颜色数 ( m )。

输出

  • 所有可能的着色方案,或者输出 “NO” 表示不存在着色方案。

步骤

  1. 构建邻接矩阵:使用一个二维数组 ( a ) 来表示图 ( G ) 的邻接矩阵,其中 ( a[i][j] = 1 ) 表示顶点 ( i ) 和顶点 ( j ) 之间有边。
    在这里插入图片描述
    下图表示 每个顶点有m种 着色方法

在这里插入图片描述
3. 着色过程

  • 从顶点 ( 1 ) 开始,尝试为其着色。
  • 对于每个顶点 ( i ),检查所有相邻顶点 ( j ),确保 ( x[i] ≠ x[j] )。
  • 如果当前颜色无法满足条件,尝试下一个颜色,直到找到合适的颜色或所有颜色都尝试完毕。
  • 如果所有颜色都无法满足条件,则回溯到上一个顶点,改变其颜色。
  1. 记录着色方案:当所有顶点都被着色时,记录当前的着色方案。

示例

假设我们有一个图 ( G ) 包含 4个顶点,我们尝试使用 3 种颜色对其进行着色。通过上述算法,我们可以找到所有可能的着色方案。

假设的图 ( G ) 和颜色

  • 顶点集合 ( V = {1, 2, 3, 4} )
  • 边集合 ( E = {(1, 2), (1, 3), (2, 3), (3, 4)} )
  • 颜色集合 ( C = {红, 蓝, 绿} )

步骤

1. 构建邻接矩阵

首先,我们需要构建一个邻接矩阵来表示图中顶点之间的连接关系。如果顶点 ( i ) 和顶点 ( j ) 之间有边,则 ( a[i][j] = 1 ),否则 ( a[i][j] = 0 )。

1234
10110
21010
31101
40010

2. 着色过程

我们将使用回溯法来尝试为每个顶点着色。

2.1 选择起始点

我们从顶点 1 开始着色。

2.2 为顶点 1 着色

我们尝试为顶点 1 着色。由于没有相邻的顶点,我们可以任意选择一种颜色。假设我们选择红色。

  • 颜色数组:[ 红, _ , _ , _ ]
2.3 为顶点 2 着色

顶点 2 与顶点 1 相邻,因此不能着同样的颜色(红色)。我们尝试其他颜色。

  • 尝试蓝色:可以,因为与顶点 1 不同。
  • 颜色数组:[ 红, 蓝, _ , _ ]
2.4 为顶点 3 着色

顶点 3 与顶点 1 和 2 相邻,因此不能着红色或蓝色。

  • 尝试绿色:可以,因为与顶点 1 和 2 不同。
  • 颜色数组:[ 红, 蓝, 绿, _ ]
2.5 为顶点 4 着色

顶点 4 与顶点 3 相邻,因此不能着绿色。

  • 尝试红色:不可以,因为与顶点 3 相同。
  • 尝试蓝色:可以。
  • 颜色数组:[ 红, 蓝, 绿, 蓝 ]

3. 完成着色

我们成功为所有顶点着色,得到一个有效的着色方案。

代码

#include "stdio.h"

// 定义全局变量
int n, m; // n 是图中顶点的数量,m 是可以使用的颜色数量

int a[100][100]; // 定义一个 100x100 的二维数组 a,用来存储图的邻接矩阵
int x[100]; // 定义一个数组 x,用来存储当前顶点的着色方案
int sum = 0; // 定义一个变量 sum,用来记录总共找到的着色方案的数量

// 输入函数,用于获取用户输入的图的信息
void input() {
    printf("输入顶点数n和着色数m:\n"); // 提示用户输入顶点数和颜色数
    scanf("%d %d", &n, &m); // 读取用户输入的顶点数和颜色数

    printf("输入无向图的邻接矩阵:\n"); // 提示用户输入邻接矩阵
    for (int i = 1; i <= n; i++) { // 遍历每个顶点
        for (int j = 1; j <= n; j++) // 遍历每个顶点的邻接顶点
            scanf("%d", &a[i][j]); // 读取邻接矩阵的值
        printf("\n"); // 换行
    }
}

// 检查函数,用于检查当前顶点是否可以着指定颜色
int ok(int k) {
    for (int j = 1; j <= n; j++) // 遍历所有顶点
        if (a[k][j] && (x[j] == x[k])) // 如果顶点 k 和顶点 j 相邻,并且颜色相同
            return 0; // 返回 0,表示不可以着这个颜色
    return 1; // 返回 1,表示可以着这个颜色
}

// 回溯函数,用于尝试所有可能的着色方案
void backtrack(int t) {
    if (t > n) { // 如果已经为所有顶点尝试了着色
        sum++; // 着色方案数加一
    } else {
        for (int i = 1; i <= m; i++) { // 尝试每种颜色
            x[t] = i; // 给顶点 t 着色
            if (ok(t) == 1) backtrack(t + 1); // 如果可以着这个颜色,递归尝试下一个顶点
            x[t] = 0; // 回溯,撤销当前顶点的着色
        }
    }
}

// 主函数,用于启动着色算法
int color() {
    sum = 0; // 初始化着色方案数为 0
    backtrack(1); // 从第一个顶点开始尝试着色
    return sum; // 返回找到的着色方案数
}

// 主函数,程序的入口
int main() {
    input(); // 调用输入函数
    color(); // 调用着色函数
    printf("着色方案数为:%d\n", sum); // 输出找到的着色方案数
    return 0; // 程序结束
}

在这里插入图片描述

复杂度分析

图m可着色问题的解空间树中,内结点个数是:
在这里插入图片描述

对于每一个内结点,在最坏情况下,用ok检查当前扩展结点每一个儿子的颜色可用性需耗时O(mn)。

因此,回溯法总的时间耗费是
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2101104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sentence-BERT实现文本匹配【回归目标函数】

引言 上篇文章我们通过Sentence-Bert提出的分类目标函数来训练句子嵌入模型&#xff0c;本文同样基于Sentence-Bert的架构&#xff0c;但改用回归目标函数。 架构 如上图&#xff0c;计算两个句嵌入 u \pmb u u和 v \pmb v v​之间的余弦相似度&#xff0c;然后可以使用均方误…

如何通过住宅代理优化SERP表现:提升SEO排名的实用指南

引言 什么是SERP&#xff1f;包含哪些内容&#xff1f; 为什么SERP对SEO至关重要&#xff1f; 如何优化SERP表现&#xff1f; 总结 引言 在当今竞争激烈的数字营销环境中&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已成为企业提升在线可见性和吸引有机流量的关键…

matlab2024a/2023/2022/2020/matlab2019 如何plot画局部放大图(已解决)

matlab 2024&#xff1b;matlab 2023&#xff1b;matlab 2022&#xff1b;matlab 2021&#xff1b;matlab 2020&#xff1b;matlab 2019 matlab 2017一下的 使用magnify.m 进行局部放大图操作是没有问题的。 新版本 采用magnify.m 很难操作。 为什么要局部放大 局部方…

【王树森】Few-Shot Learning (3/3):Pretraining + Fine Tuning(个人向笔记)

Preliminary Few-Shot Learning 很简单&#xff0c;但是却能达到比较高的准确度&#xff0c;相反一些复杂的模型反而不能达到很高的准确率 1. Cosine Similarity 余弦相似度可以衡量两个向量的相似度 假设两个向量的长度都是1&#xff1a;那么它们余弦相似度的计算方法如下…

HarmonyOS开发实战( Beta5版)线程间通信场景最佳实践

简介 在应用开发中&#xff0c;经常会需要处理一些耗时的任务&#xff0c;如果全部放在主线程中执行就会导致阻塞&#xff0c;从而引起卡顿或者掉帧现象&#xff0c;降低用户体验&#xff0c;此时就可以将这些耗时操作放到子线程中处理。通常情况下&#xff0c;子线程可以独立…

bcftools报错|The sequence “chr1“ not defined in the header: chr1.recode.vcf

1、报错信息 The sequence "chr1" not defined in the header: chr1.recode.vcf (Quick workaround: index the file.) 所使用的命令&#xff0c;目的是想合并所提取的特定染色体。 bcftools concat -O v / -o varscan.indel_merged.vcf chr1.recode.vcf chr2.reco…

超好用的图纸加密软件排行榜 | 2024图纸加密软件的七款最优选择!

数字化设计日益普及的今天&#xff0c;图纸作为设计与工程的核心载体&#xff0c;其安全性成为了企业和设计师们最为关注的焦点之一。 面对日益复杂的数据泄露风险&#xff0c;如何有效地保护图纸文件的安全呢&#xff1f; 下面&#xff0c;我们就来探讨一下2024图纸加密软件的…

Python的10个文件对比与合并高效策略

文末赠免费精品编程资料~~ 在日常编程或数据分析工作中&#xff0c;经常需要处理多个文件的对比与合并任务。Python因其强大的文件处理能力和丰富的库支持&#xff0c;成为了处理这类任务的理想选择。下面&#xff0c;我们将逐步探索10种高效的文件对比与合并策略&#xff0c;…

OpenGL/GLUT实践:粒子系统,并添加纹理、动态模糊、边界碰撞(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub&#xff1a;A-UESTCer-s-Code 文章目录 1 运行效果2 实验过程2.1 基本粒子系统2.1.1 定义粒子结构2.1.2 创建粒子并初始化2.1.2.1 创建粒子2.1.2.2 初始化 2.1.3 粒子状态更新与绘制2.1.3.1 绘制2.1.3.2 更新 2.1.4 实现效果 2.2 添加纹理2.2.1 纹理添加2.2.2 渲染…

PostgreSQL + PostGIS:空间数据存储及管理解决方案

在数据库领域&#xff0c;PostgreSQL 已成为最强大、最通用的选项之一。它管理大量数据的能力、对 SQL 标准的遵守以及可扩展的架构使其受到学术界和工业界的喜爱。然而&#xff0c;真正让 PostgreSQL 脱颖而出的原因之一是它与PostGIS的集成&#xff0c;这是一个允许您有效处理…

第七课,条件表达式与初识分支判断

一&#xff0c;什么是判断 判断&#xff0c;就是在做某件事前&#xff0c;先问问满不满足条件。 进行逻辑判断&#xff0c;是生活中常见的行为。 “今天出门你要带伞吗&#xff1f;” “那得看天气怎么样&#xff0c;如果下雨或者太阳太大就带伞&#xff0c;否则就不带。”…

内存卡乱码问题解析恢复方案

一、内存卡乱码现象探析 在数字化时代&#xff0c;内存卡作为便携式数据存储设备&#xff0c;广泛应用于手机、相机、行车记录仪等多种电子设备中。然而&#xff0c;不少用户在使用过程中会遇到内存卡乱码的问题&#xff0c;即原本有序存储的文件突然变得无法识别&#xff0c;…

【前端面试】设计循环双端队列javascript

题目 https://leetcode.cn/problems/design-circular-deque/description/ 存储循环队列的向量空间是循环的,用通俗的话来讲,就是我们在做next或者prev操作时,不会发生溢出 取模、或者直接判断是否为0/size返回一个值。 数组实现 用函数来实现一个类,定义容量、头尾指针…

青远生态为云南林业规划院定制开发的自然保护地规划智能编制系统顺利通过验收

8月30日&#xff0c;青远生态为云南省林业调查规划院开发的自然保护地规划智能编制系统顺利通过验收。该系统具有智能推荐规划内容、自动生成投资估算表、智能编制规划报告等功能&#xff0c;集合了拉丁名填充、表格制作等丰富实用的工具&#xff0c;显著提升了规划工作的效率和…

电力系统有滤波器还需要装电抗器吗

在电力系统中&#xff0c;滤波器和电抗器各有不同的功能&#xff0c;尽管它们都能改善电力质量。是否需要同时安装滤波器和电抗器&#xff0c;取决于系统的具体需求和现状。以下是一些考虑因素&#xff1a; 1、滤波器的功能&#xff1a; 谐波滤波&#xff1a;滤波器主要用于抑…

基于vue框架的超市会员管理系统设计与实现xeb8c(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;会员,商品分类,商品信息,订单信息,积分等级,礼品信息,礼品兑换 开题报告内容 基于Vue框架的超市会员管理系统设计与实现开题报告 一、研究背景与意义 随着消费者对个性化服务和优惠活动需求的增加&#xff0c;超市会员管理成为提升顾…

Docker安装及验证,小白必备

Docker安装 本教程以centos系统为例 1、Docker安装前准备工作 切换国内源 cp -a /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak #备份设置为华为云的yum wget -O /etc/yum.repos.d/CentOS-Base.repo https://repo.huaweicloud.com/repository…

专用于理解游戏场景的开源大模型-VideoGameBunny

大模型在游戏开发领域扮演了重要角色&#xff0c;从AI机器人生成到场景搭建覆盖各个领域。但在游戏场景理解、图像识别、内容描述方面很差。 为了解决这些难题&#xff0c;加拿大阿尔伯塔的研究人员专门开源了一款针对游戏领域的大模型VideoGameBunny&#xff08;以下简称“VG…

7-8月月报 | Apache SeaTunnel社区进展一览

各位热爱 Apache SeaTunnel 的小伙伴们&#xff0c;社区 7-8 月份月报来啦&#xff01;这两个月项目有了哪些进展&#xff1f;又有谁登上了我们社区的贡献者榜单呢&#xff1f;快来一睹为快吧。 Merge Stars 感谢以下小伙伴上两个月为 Apache SeaTunnel 项目和社区发展所做的…

非时序检查(Non-Sequential Check)

单元或宏&#xff08;macro&#xff09;的库文件可以将时序弧指定为非时序&#xff08;non-sequential&#xff09;检查&#xff0c;例如两个数据引脚之间的时序弧。非时序检查是指两个引脚之间的检查&#xff0c;两者都不是时钟。一个引脚是约束引脚&#xff0c;其作用类似于数…