图着色问题

1、有m种颜色,对n个节点进行着色,相邻节点颜色不能相同,可以有多少种着色方法?回溯

package com.wangyi;

import java.util.Arrays;

public class GraphColor {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GraphColor c=new GraphColor();
        c.addColor();
        System.out.println(c.count);
    }

    //m种颜色,可以有多少不同的着色法
    int count=0;//成功着色的个数
    int n=0;
    int color[];
    int m=0;
    int [][]res={{0,1,1,1,0},{1,0,0,0,1},{1,0,0,0,1},{1,0,0,0,1},{0,1,1,1,0}};
    public void addColor(){
        n=res.length;
        m=2;
        color=new int[n];
        Arrays.fill(color, -1);
        backTrace(0);
    }

    public void backTrace(int i){
        if(i>=n){
            count++;
        }else{
            for(int j=0;j<m;j++){
                color[i]=j;
                if(isOk(i))backTrace(i+1);
                color[i]=-1;
            }
        }
    }

    public boolean isOk(int i){
        for(int j=0;j<n;j++){
            if(res[i][j]==1&&color[j]==color[i])return false;
        }
        return true;
    }
}

2、有一个n×n的矩阵,最少可以用多少颜色进行着色,相邻的两个节点颜色不能相同。解法:贪心算法,首先根据节点的度数进行排序,依次给度数较大的节点着色。

package com.wangyi;

import java.util.Arrays;
import java.util.Comparator;

public class GraphColor2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GraphColor2 c=new GraphColor2();
        c.addColor();
        System.out.println(c.count);
    }

    //至少需要多少种颜色
    int count=0;
    int n=0;
    int color[];
    int [][]res={{0,1,1,1,0},{0,0,0,0,1},{0,0,0,0,1},{1,0,0,0,1},{0,1,1,1,0}};
    public void addColor(){
        n=res.length;
        color=new int[n];
        // sort array by degree
        int[] temp=calculateDu();
        //set color according to degree
        for(int i=0;i<n;i++){
            int colori=0;
            color[temp[i]]=colori;
            while(!isOk(temp[i])){
                colori++;
                color[temp[i]]=colori;
                count=Math.max(count, colori+1);
            }
        }
    }
    public int[] calculateDu(){
        int val[]=new int[n];
        for(int i=0;i<n;i++){
            int num=0;
            for(int j=0;j<n;j++){
                if(res[i][j]==1)val[i]=++num;
            }
        }
        Pair[] pairs=new Pair[n];
        for(int i=0;i<n;i++){
            pairs[i]=new Pair(i,val[i]);
        }
        Arrays.sort(pairs,new Comparator<Pair>(){

            @Override
            public int compare(Pair arg0, Pair arg1) {
                // TODO Auto-generated method stub
                if(arg0.val>arg1.val)return 1;
                else if(arg0.val==arg1.val)return 0;
                return -1;
            }

        });
        for(int i=0;i<n;i++){
            val[i]=pairs[i].index;
        }
        return val;

    }

    public boolean isOk(int i){
        for(int j=0;j<n;j++){
            if(res[i][j]==1&&color[j]==color[i])return false;
        }
        return true;
    }

    class Pair{
        int index;
        int val;
        public Pair(int index,int val){
            this.index=index;
            this.val=val;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值