图的m着色问题
Posted zjd-ac
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的m着色问题相关的知识,希望对你有一定的参考价值。
图的m着色问题(color)
[题目描述]
给定无向连通图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)。
[输出格式]
将计算出的不同的着色方案数输出。
[输入样例]
5 8 4
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
[输出样例]
48
[解法]
此题大致思路是DFS每次确定一个点的颜色,直到确定图所有点的颜色。还有就是要会存图,通常用tu[x][y]来表示两点之间的关系,tu[x][y]=-1表示x、y两点无连接;非-1表示两点的权值或距离。我的代码中应题做了一些改变:用tu[x][y] 来表示两点之间的关系和颜色,tu[x][y]=-1表示x、y两点无连接;tu[x][y]=0表示y点没有确定颜色;tu[x][y]=k表示y点颜色为k。有了这些写代码就变得异常的简单,只需注意几个细节。
细节1:
初始化:初始值为-1,表示所有点都没有连接。
点的连接为双向的!点的连接为双向的!点的连接为双向的!
并且此时x、y都是没有确定颜色的。
细节2:
回溯时要注意只回溯与step有连接的点!
否则回导致所有点对step都有联系
还有一定要吧step点本身排除不然会没有解,
因为不管什么时候step点的颜色都与step点的颜色一样
[代码(AC)]
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <string> 5 #include <cstring> 6 #include <algorithm> 7 using namespace std; 8 int tu[1000][1000]; 9 int n,k,m; 10 long long ans=0; 11 void dfs(int step){ 12 if(step>n){ 13 ++ans; 14 return ; 15 } 16 for(int i=1;i<=m;++i){//试探每种颜色 17 bool flag=true; 18 for(int j=1;j<=n;++j){ 19 if(tu[step][j]!=-1&&i==tu[step][j]){ 20 flag=false; 21 break; 22 } 23 } 24 if(flag){ 25 for(int j=1;j<=n;++j){ 26 if(tu[step][j]!=-1&&j!=step){ 27 tu[j][step]=i; 28 } 29 } 30 dfs(step+1); 31 for(int j=1;j<=n;++j){ 32 if(tu[step][j]!=-1&&j!=step){ 33 tu[j][step]=0; 34 } 35 } 36 } 37 } 38 } 39 int main(){ 40 freopen("color.in","r",stdin); 41 freopen("color.out","w",stdout); 42 memset(tu,-1,sizeof(tu)); 43 scanf("%d%d%d",&n,&k,&m); 44 for(int i=0;i<k;++i){ 45 int x,y; 46 scanf("%d%d",&x,&y); 47 tu[x][y]=0; 48 tu[y][x]=0; 49 } 50 dfs(1); 51 printf("%d",ans); 52 return 0; 53 }
2018-10-06 13:16:17
以上是关于图的m着色问题的主要内容,如果未能解决你的问题,请参考以下文章