1.问题
给定无向连通图G和m种颜色,用这些颜色给图的顶点着色,每个顶点一种颜色。如果要求G的每条边的两个顶点着不同颜色。给出所有可能的着色方案;如果不存在,则回答“NO”。
2.解析
算法思路:
- t=1->n 对当前第t个顶点开始着色:
- if: t>n 则已求得一个解,输出着色方案即可
- else:依次对顶点t着色(1-m)
- if:t与所有其它相邻顶点无颜色冲突,则继续为下一顶点着色;其中判断标准为:同相邻节点所有节点的颜色比较,如果有该节点且颜色有重复,都不符合要求,否则继续检验后序的位置。
- else: 回溯,测试下一颜色。
3.设计
//判断给点t着色为x[t]是否可行
bool OK(int t){
//可行的条件是当前点相邻的点不能与之同色
for(int i=1;i<t;i++)
if(a[i][t]==1&&x[i]==x[t])
return false;
//如果所有与之相邻的点都不与之同色
return true;
}
void getsum(int i){
//i>n说明找到了一个可行的涂色方案
if(i>n){
sum++;//涂色方案数++
//输出解向量
for(int k=1;k<=n;k++)
cout<<x[k]<<" ";
cout<<endl;
return ;
}
//还没有到叶子节点,需要给当前节点可行的涂色
else{
for(int k=1;k<=m;k++){ //子树是一个m叉树
x[i]=k;//给第i个顶点着第k种颜色
if(OK(i))
getsum(i+1);
x[i]=0;//如果给第i个顶点着第k种颜色不可行
//不涂色,便于后续涂色
}
}
return ;//如果当前节点所有颜色都不可行,结束对子树的遍历,返回
}
4.分析
5.源码
https://github.com/Chenzh0205/Algorithm/tree/main/%E4%BD%9C%E4%B8%9A12