【名词解释】
第一行输入两个整数
代表顶点数量、边数量。
此后
行,第
行输入两个整数
和
,表示图上第
条边双向连接顶点
和
。
图可能存在重边。不存在自环、保证连通。
如果给定的图不是一张二分图,输出
;否则输出
。
5 6 1 2 2 3 3 4 4 1 4 5 5 2
YES
在这个样例中,把顶点
点染色为白,
点染色为黑,即可满足二分图要求,所以这个图是二分图。
5 4 1 2 2 3 3 1 4 5
NO
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-07-07 优化题面文本与格式
2. 2025-11-28 第一组样例与实际边数不符,修正。模板题为便于测试,将时间限制扩充至 5s,空间限制扩充至 1024MB。
3. 2025-12-05 对题面与数据进行了微调,以匹配整套模板题(从
增加到
,输出修改为全大写的
和
,去除了题面背景,增加了重边数据)。
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;
}
}