二分图:
当且仅当图中不含有奇数环,两个集合内部的内部没有边
题目描述:
给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。
请你判断这个图是否是二分图。
输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 u 和 v,表示点 u 和点 v 之间存在一条边。
输出格式
如果给定图是二分图,则输出 Yes,否则输出 No。
数据范围
1≤n,m≤105
输入样例:
4 4
1 3
1 4
2 3
2 4
输出样例:
Yes
代码实现:
import java.io.*;
import java.util.*;
public class Main{
public static int[] e = new int[2 * 100010];
public static int[] ne = new int[2 * 100010];
public static int[] h = new int[100010];
public static int[] st = new int[100010];
public static int idx = 0;
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] lens = br.readLine().split(" ");
int n = Integer.parseInt(lens[0]);
int m = Integer.parseInt(lens[1]);
Arrays.fill(h, -1);
while(m-- > 0){
String[] res = br.readLine().split(" ");
int a = Integer.parseInt(res[0]);
int b = Integer.parseInt(res[1]);
add(a, b);
add(b, a);
}
boolean flag = true;
for (int i = 1; i <= n; i++){
if (st[i] == 0){
if (!dfs(i, 1)){
flag = false;
break;
}
}
}
if (flag) System.out.println("Yes");
else System.out.println("No");
}
public static boolean dfs(int x, int c){
st[x] = c;
for (int i = h[x]; i != -1; i = ne[i]){
int j = e[i];
if (st[j] == 0){
if (!dfs(j, 3 - c)) return false; //将j节点染色为2,即与当前节点不同
}else if (st[j] == c) return false;//如果j节点的颜色和当前节点相同,则表示染色失败,无法二分
}
return true;
}
public static void add(int a, int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
}
bfs版:
import java.io.*;
import java.util.*;
public class Main{
public static int[] e = new int[2 * 100010];
public static int[] ne = new int[2 * 100010];
public static int[] h = new int[100010];
public static int[] st = new int[100010];
public static int idx = 0;
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] lens = br.readLine().split(" ");
int n = Integer.parseInt(lens[0]);
int m = Integer.parseInt(lens[1]);
Arrays.fill(h, -1);
while(m-- > 0){
String[] res = br.readLine().split(" ");
int a = Integer.parseInt(res[0]);
int b = Integer.parseInt(res[1]);
add(a, b);
add(b, a);
}
if(bfs(n)) System.out.println("Yes");
else System.out.println("No");
}
public static boolean bfs(int n){
Queue<Integer> q = new LinkedList<>();
for (int i = 1; i <= n; i++){
if(st[i] == 0){
st[i] = 1;
q.offer(i);
while(!q.isEmpty()){
int t = q.poll();
for (int j = h[t]; j != -1; j = ne[j]){
int k = e[j];
if(st[k] == 0){
st[k] = 3 - st[t];
q.offer(k);
}else if(st[k] == st[t]) return false;
}
}
}
}
return true;
}
public static void add(int a, int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
}