首页 > 试题广场 >

【模板】二分图判定

[编程题]【模板】二分图判定
  • 热度指数:2251 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 1024M,其他语言2048M
  • 算法知识视频讲解
\hspace{15pt}给定一张包含 n 个节点、m 条无向边的图(不保证连通)。若存在一种方式可将每个节点染为黑色或白色,使得任意一条边的两个端点颜色不同,则称该图为二分图
\hspace{15pt}请判断所给图是否为二分图。

【名词解释】
\hspace{15pt}二分图:可将顶点集合划分为两个独立集,且所有边均连接不同集合的图。

输入描述:
\hspace{15pt}第一行输入两个整数 n,m\left(1\leqq n,m\leqq 10^{5}\right)——节点数与边数。 
\hspace{15pt}接下来的 m 行,每行输入两个整数 u_i,v_i\left(1\leqq u_i,v_i\leqq n\right),表示存在一条连接 u_iv_i 的无向边。保证无重边、自环。


输出描述:
\hspace{15pt}若该图为二分图,输出Yes;否则输出No。
示例1

输入

5 6
1 2
2 3
3 4
4 1
4 5
5 2

输出

Yes

说明

如图,把1, 3, 5点染色为白,2, 4染色为黑,即可满足二分图要求,所以这个图是二分图。
示例2

输入

5 4
1 2
2 3
3 1
4 5

输出

No

说明

1, 2, 3号点无论如何染色都无法满足要求,所以不是二分图。

备注:
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-07-07优化题面文本与格式
2. 2025-11-28 第一组样例 m 与实际边数不符,修正。模板题为便于测试,将时间限制扩充至 5s,空间限制扩充至 1024MB。
import java.util.*;
import static java.lang.System.in;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(in);
        int n = sc.nextInt();
        int m  = sc.nextInt();
        // 建图
        HashMap<Integer, HashSet<Integer>> graph =new HashMap<>();
        
        for(int i = 0; i<m; i++){
            int curr = sc.nextInt();
            int next = sc.nextInt();
            graph.putIfAbsent(curr,new HashSet());
            graph.get(curr).add(next);
        }
        //  是n+1,因为从0开始
        int[] colors = new int[n+1];
        // 我们染色三种情况,0是没有染色到,1是一种颜色,-1是一种颜色
        boolean ans = true;
        for(int cur= 1; cur<=n; cur++){
            //对于一个从来没染过色的点,初始都为1,然后我们开始爱的魔力找圈圈
            if(colors[cur] == 0  &&  !dfs(colors,1,graph, cur ))  ans =false;
        }
        //***改的,就是为了输出简单
        String res = "Yes";
        if(!ans)  res = "No";
        
        System.out.println(res);
    }
    private static boolean dfs(int[] colors, int color, HashMap<Integer, HashSet<Integer>> graph,int cur){
       //找到了一个环,然后看他现在要给的颜色和之前的颜色是不是一样的。这个根据题意好理解。
        if(colors[cur] != 0) return colors[cur] == color;
        colors[cur] = color;
        
        //非连通图的情况,到了尾巴,发现他是个一条边,这种情况肯定是对的
        if(!graph.containsKey(cur)) return true;
        
        for(int next:  graph.get(cur)){
            if(!dfs(colors, -color, graph, next)) return false;
        }
        
        return true;
    }
}

发表于 2020-04-14 05:40:58 回复(0)