99+木头的博客&
Enjoy writing code.

[题解]图的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

posted @ 2018-10-06 13:15  99+木头  阅读(801)  评论(3编辑  收藏  举报