java---染色法判定二分图(每日一道算法2022.9.4)

注意事项
代码中涉及单链表存储邻接图,可以看我之前写的:java-单链表数组模拟
DFS在这个题里,就是搜到当前节点的所有连通点,不放例子了,感兴趣可以直接自搜

题目:
给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环
请你判断这个图是否是二分图

第一行包含两个整数 n 和 m
接下来 m 行,每行包含两个整数 u 和 v,表示点 u 和点 v 之间存在一条边

二分图定义: 百度百科_二分图

输入:
4 4
1 3
1 4
2 3
2 4
输出:
Yes
public class 二分图_染色法 {
    //n代表点的数量,m代表边的数量,h/e/ne/index是用来存储邻接表的(多个单链表),colors存储节点的颜色
    public static int N = 1000010, M = 2*N, index = 0, n, m;
    public static int[] h = new int[N], e = new int[M], ne = new int[M];
    public static int[] colors = new int[N];

    public static void main(String[] args) {
        //初始化,邻接表记得将h覆盖-1
        Scanner in = new Scanner(System.in);
        n = in.nextInt(); m = in.nextInt();
        Arrays.fill(h, -1);

        //无向图,所以节点a指向节点b,节点b也指向节点a
        while (m-- > 0) {
            int x = in.nextInt(), y = in.nextInt();
            add(x, y); add(y, x);
        }

        //result保存判断是否是二分图的结果
        //思路为遍历每一个点,如果节点没有被染色,那么就染色为1
        //同时将所有该节点能够连接的节点进行染色(dfs实现)
        //注意这里i是1开始,因为节点是从1开始的,从0开始会导致之后colors的判断出错,因为0节点并不存在
        boolean result = true;
        for (int i = 1; i<=n; i++) {
            if (colors[i] == 0) {
                if (!dfs(i, 1)) {
                    result = false;
                    break;
                }
            }
        }

        if (result) System.out.println("Yes");
        else System.out.println("No");
    }

    //单链表的头节点插入操作
    public static void add(int x, int y) {
        e[index] = y;
        ne[index] = h[x];
        h[x] = index++;
    }

    //dfs传入两个数据,i是节点,c是节点的颜色
    //如果存在冲突,返回false
    public static boolean dfs(int u, int c) {
        //颜色赋值,单链表的遍历
        //3-c是:如果当前节点颜色为1,那么下一个节点染色为2,如果当前节点颜色为2,那么下一个节点染色为1
        //如果说下一个节点已经被染过颜色,那么判断一下当前节点和下一个节点的颜色是否相同,不同就说明不是二分图
        colors[u] = c;
        for (int i = h[u]; i!=-1; i = ne[i]) {
            int j = e[i];
            if (colors[j] == 0) {
                if (!dfs(j, 3-c)) return false;
            }
            else {
                if (c == colors[j]) return false;
            }
        }
        return true;
    }
}

总体思路就是对每个点进行染色为1和2,如果说当节点a和节点b相连,且a和b颜色相同,说明不是二分图

声明:算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流

你可能感兴趣的:(算法,算法,java,图论)