洛谷P2817-图m的着色问题-dfs+递归

题目 图的m着色问题

题目背景

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

题目描述

对于给定的无向连通图 G 和 m 种不同的颜色,编程计算图的所有不同的着色法。

输入格式

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

输出格式

程序运行结束时,将计算出的不同的着色方案数输出。

样例 #1

样例输入 #1
5 8 4
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
样例输出 #1
48

提示

n<=100;k<=2500;

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

保证答案不超过20000。

分析

用邻接矩阵f[][]二维数组存储图
用数组color[]存储每个结点的颜色,初始化为0
对每个点进行 for 循环,猜测赋值的颜色,然后递归对下一个点进行猜测

AC代码

#include<stdio.h>
#include<cstring>

int n ,k,m,x,y;
bool f[105][105];//存两个点是否连通
int color[105];//存每个点的颜色
int num=0;

bool check(int sum) {//检查与该点相连的点的颜色是否重复了
	int i;
	for(i=1; i<=sum; i++) {
		if(f[i][sum]==true && color[i]==color[sum]) {
			return false;//重复了
		}
	}
	return true;//没有重复
}

void dfs(int s) {
	if(s>n) { //说明所有点的颜色都赋值完了
		num++;
		return;
	}
	int j;
	for(j=1; j<=m; j++) { //颜色的种类,给当前的点什么颜色呢?-for循环挑
		color[s]=j;//将点s赋值为颜色j
		if(check(s)==true)//不冲突就对下一个点上色
			dfs(s+1);
			color[s]=0;//如果冲突或者清除前面的赋值操作,赋值为0
	}
}
int main() {
//输入数据,存储图像
	scanf("%d%d%d",&n,&k,&m);
	int i; 
	for(i=1; i<=k; i++) {
		scanf("%d%d",&x,&y);
		f[x][y]=true;//有边
		f[y][x]=true;
	}
	
	dfs(1);//开始给第一个点赋予颜色
	printf("%d\n",num);
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MORE_77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值