图m的着色问题

您所在的位置:网站首页 图的染色问题及其在实际问题中的应用 图m的着色问题

图m的着色问题

2024-07-13 09:46:35| 来源: 网络整理| 查看: 265

题目描述

给定无向连通图 G 和 m 种不同的颜色。用这些颜色为图 G 的各顶点着色,每个顶点着一种颜色。如果有一种着色法使 G 中每条边的 22 个顶点着不同颜色,则称这个图是 m 可着色的。图的 m 着色问题是对于给定图 G 和 m 种颜色,找出所有不同的着色法。

输入

第 1 行有 3 个正整数n,k,m,表示给定的图 G 有 n 个顶点和 k 条边,m 种颜色。顶点编号为 1,2,…,m。接下来的 k 行中,每行有 2 个正整数 u,v,表示图 G 的一条边(u,v)。

输出

将计算出的不同的着色方案数输出。

样例输入输出

样例输入 #1

5 8 4 1 2 1 3 1 4 2 3 2 4 2 5 3 4 4 5

样例输出 #1

48

数据范围

数据保证,1≤n≤100,1≤k≤2500。

在 n 很大时保证 k 足够大。

保证答案不超过 20000。

数据为在满足上述条件的合法数据中随机采样得到。

差不多是这样的:

 分析:

        1.判断颜色是否符合要求 对于每个节点 u,如果它与另一个节点 v 有边相连,且这两个节点颜色相同,那么就不能把节点 u 涂为该颜色。因此,需要定义一个函数 ok() 来判断某个节点染上某种颜色是否符合要求。具体来说,ok(u, c) 函数返回值为true表示节点 u 可以涂上颜色 c,否则返回false。

      2.使用深度优先搜索

使用深度优先搜索(DFS)从解空间树的根节点开始搜索,并在每个分支结点处调用 ok() 函数来剪枝。如果在整棵解空间树中找到了一组可行解,那么算法就停止搜索并输出结果。如果找不到任何一个可行解,则算法输出无解信息。

具体实现过程:

首先,需要定义一个二维数组 G[ ][ ],用于存储图中的边。其中,G[u][v] == 1 表示节点 u 和节点 v 之间有边相连,反之为 0。同时,还需要定义一个一维数组 color[ ],用于存储每个节点的颜色。

首先将所有边权赋值为 0,即不存在边。然后,读入所有边,将对应的边权赋值为 1。读入颜色数 m,并从节点 1 开始做深度优先搜索,依次尝试给每个节点涂上不同的颜色。在每个分支结点处,使用 ok() 函数来判断是否符合要求。如果染色成功,则继续对下一个节点做深度优先搜索。如果找到了一组可行解,则输出结果

        3.时间复杂度(转载于kurayamasy的【时间复杂度计算方法以及常见的时间复杂度】链接:https://blog.csdn.net/m0_63850771/article/details/127229462)

概念:

  一般来说要确定算法的运行时间,只有你将他拿到机器上去测试一下才能确定,但是过于麻烦,那么有没有一种方法能够估算该算法的运行时间呢?因此引入了时间复杂度这个概念。

    时间复杂度是一种函数,定量地描述了该算法运行的时间。既然是一种函数,就涉及到自变量与因变量。因变量代表是时间复杂的规模,自变量是时间复杂度的执行时间。这里的执行时间并不是秒,分钟这类的具体时间  ,它表示的是一种“执行次数”。要想计算时间复杂度首先得找到该算法中的循环,算法中循环执行的次数就是算法的时间复杂度 。

     算法的时间复杂度的具体表示为:用大写的 O 来体现算法时间复杂度如O(f(n)),称之为 大 O 记数法。

算法:

一,给定 n个元素 的数组a[n],求其中 奇数 有多少个。判断一个数是偶数还是奇数,只需要求它除上 2 的余数是 0 还是 1,把所有数都判断一遍,并且对符合条件的情况进行计数,最后返回这个计数器就是答案,需要遍历所有的数。

二,求下面函数的时间复杂度

int fun(int n) {    int cnt = 0;   for(int i = 0;i < n;i++)    {      for(int j = 0; j      ++cnt;    }//一层循环,循环n次      for(int l = 0;l    assert(a); for(int end = n; end>0; end--)     {       int exchange = 0;        for(int i = 1; i                 swap(&a[i],&a[i-1]);                  exchange = 1;                }             }             if(exchange==0)            break;      } }

例如在这个冒泡排序中,我们需要将无序数组转化为有序数组的一种算法,它并不像上题一样是简单的双层嵌套循环,很容易想到它的循环次数是一个等差数列,第一次循环n-1次,第二次n-2次.....一直到1.因此为n-1+n-2+n-3.....+1 = n*(n-1)/2,由上面所说的规律时间复杂度为O(N*N).

  通过上面的例子我们看出,大O渐近表示法去掉了对结果影响不大的项,简洁明了地表示出了时间复杂度.在实际情况中一般只关注算法的最坏运行情况.

   例如在上述冒泡排序中,如果给定的数组就已经是有序的了,那么就是它的最好情况,时间复杂度为O(N).但是如果有非常多的数据很显然我们看不出它到底是否为最好情况,所以我们必须用最坏的期望来计算所以它是O(N*N).

四, int fun(int n) {   int i = 0;int cnt = 0;    for( i; i     int left = 0, right = n - 1;     while(l     int i;     if(n == 1) {         return false;     }     int sqrtn = sqrt(n);     for(int i = 2; i             return false;         }     }     return true; }

只需要枚举所有小于根号n的数,使n与其相除 ,这样时间复杂度就小了很多.那为什么只需要枚举小于根号n个数呢?

因为假设n是数k的因子,那么n^2也必定是数k的因子,所以不需要枚举小于k这么多数,只需要枚举根号n个数就可以了.

6,阶乘阶 阶乘阶的讨论没有意义,阶乘级的时间复杂度一般在刷题时过不了,一般会用动态规划代替.

打住,文章似乎已经太长了  

代码区

考察点:

数组

dfs

scanf和printf(比cin cout快一点)

贴代码:

#include #include #include using namespace std; int n,k,m,x,y,i,ans=0; int a[1001][1001],f[1001][1001]; void dfs(int dep) { int i,j; if (dep==n+1) { ans++; return; } for (i=1;i


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭