图的dfs_二分图着色

  把相邻顶点染成不同颜色的问题叫做图的着色问题。
对图进行染色所需的最小颜色数,称为最小着色数。
  最小着色数为2的图称为二分图。
  给定一个具有n个顶点的图,要给图上每个顶点染色,并且要使相邻的顶点的颜色不同、问能否最多用2种颜色进行染色?没有重边和自环。

参考代码:

import java.util.ArrayList;
import java.util.List;

//邻接表
class   GraphNode {
    public int val;
    private List<GraphNode> neighbors;//邻居

    public boolean checked = false;

    public GraphNode(int val) {
        this.val = val;
    }

    public GraphNode getNeighbor(int i) {
        return neighbors.get(i);
    }

    public void add(GraphNode node) {
        if (this.neighbors == null)
            this.neighbors = new ArrayList<>();
        this.neighbors.add(node);
    }

    public int size() {
        return this.neighbors.size();
    }
}

class MyNode extends GraphNode {
    int color;

    public MyNode(int val) {
        super(val);
    }

    public MyNode(int val, int color) {
        super(val);
        this.color = color;
    }
}
public class Main {
    public static void main(String[] args) {
        MyNode n1 = new MyNode(1);
        MyNode n2 = new MyNode(2);
        MyNode n3 = new MyNode(3);
        MyNode n4 = new MyNode(4);

        n1.add(n2);
        n1.add(n4);

        n2.add(n1);
        n2.add(n3);

        n3.add(n2);
        n3.add(n4);

        n4.add(n1);
        n4.add(n3);
        
        //从节点n1开始着色(其实可以从任意顶点开始着色)
        System.out.println(dfs(n1, 1));
    }

    private static boolean dfs(MyNode node, int c) {
        //color同时具有是否被访问、代表具体颜色的功能(两种颜色设为c和-c)
        node.color = c;
        //遍历所有相邻顶点
        for (int i = 0; i < node.size(); ++i) {
            //具体的相邻顶点
            MyNode neighbor = (MyNode) node.getNeighbor(i);
            //如果相邻节点颜色一样,返回false
            if (neighbor.color == c) {
                return false;
            }
            //如果没有被染色,就染不同颜色(-c)进行递归
            if (neighbor.color == 0) {
                boolean res = dfs(neighbor, -c);
                //从当前节点开始染色无法形成二分图,就返回false
                if (!res) {
                    return false;
                }
            }
        }
        //从当前节点开始染色,能形成二分图
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值