着色问题描述:
给图中的结点涂上颜色,相邻(直接连通)的结点涂的颜色不能相同。
方法1:回溯法:
回溯法求出的涂色方法是全的,涂色方案不止一种。
public class ZhuoSe {
//颜色的种类
public int colors[] = new int[]{1,2,3};
//结点个数
public int n;
//每个结点图什么颜色
public int x[];
public static void main(String args[]){
//邻接矩阵
int a[][] = {{0,1,0,1},
{1,0,1,0},
{0,1,0,1},
{1,0,1,0}
};
ZhuoSe zhuo = new ZhuoSe();
zhuo.x= new int[4];
//核心方法
zhuo.backtrack(a,0);
}
public ZhuoSe(){
this.n=4;
}
public void backtrack(int a[][],int t){
//如果每个结点都涂上色了
if(t>=this.n){
//输出每个结点所涂的颜色
for(int i=0;i<n;i++){
System.out.print(x[i]);
}
System.out.print("\n");
return;
}
else{
//循环每一种颜色
for(int j=0;j<colors.length;j++){
//判断是否可以涂这种颜色
if(ok(t,colors[j],a)){
//记录该结点涂什么颜色
x[t] = colors[j];
//涂过的数目加一
t= t+1;
//递归调用
backtrack( a, t);
//涂过的数目减一
t=t-1;
}
}
}
}
/***
*
* @param m //处理到的结点
* @param n //要图的颜色
* @return
*/
public boolean ok(int m,int n,int a[][]){
for(int i=0;i<m;i++){
if(x[i]==n&&a[m][i]==1){
return false;
}
}
return true;
}
}
第二中方法:贪心思想实现
思路:用一种颜色尽可能多的去图结点,然后用第二种颜色去涂,,,,,这样一次类推下去
代码:
/***
* 使用贪心算法解决着色问题
* @author user
*
*/
public class Zhuose2 {
public int colors[] = {1,2,3,4};
//结点个数
public static int n=5;
//是否已经图上了颜色
public boolean used[] = new boolean[n];
//各个结点应该图的颜色
public static int node[] = new int[n];
public static void main(String args[]){
//图的邻接矩阵
int a[][] = {
{0, 1, 1, 1, 0},
{1, 0, 1, 1, 1},
{1 ,1, 0, 1 ,0},
{1 ,1 ,1, 0 ,1},
{0, 1, 0, 1, 0},
};
Zhuose2 zhuose = new Zhuose2();
zhuose.paintColor(a);
for(int i=0;i<n;i++){
System.out.print(node[i]);
System.out.println("\n");
}
}
public void paintColor(int a[][]){
//涂过的总数
int count = 0;
//颜色的循环
for(int i=0;i<colors.length;i++){
//结点的循环
for(int j=0;j<n;j++){
//如果可以涂且还没有涂过
if(ok(a,j,i)&&used[j]==false){
node[j] = colors[i];
used[j] = true;
count++;
if(count>=n){
return;
}
}
}
}
}
/***
* 判断是否可以涂这种颜色
* @param a
* @param j
* @param n
* @return
*/
public boolean ok(int a[][],int j,int n){
for(int m=0;m<this.used.length;m++){
if(used[m]==true&&a[m][j]==1&&colors[n]==node[m]){
return false;
}
}
return true;
}
}