思路:

原理:一个图是二分图当且仅当图中不含奇数环,当且仅当染色法无矛盾!
dfs,将临点染成不同颜色,染色失败返回false
时间复杂度 O(n + m)

模板

860. 染色法判定二分图

给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。
请你判断这个图是否是二分图。
输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 u和 v,表示点 u 和点 v 之间存在一条边。
输出格式
如果给定图是二分图,则输出 Yes,否则输出 No
数据范围
1≤n,m≤105
输入样例:

  1. 4 4
  2. 1 3
  3. 1 4
  4. 2 3
  5. 2 4

输出样例:

  1. Yes

代码:

  1. // dfs
  2. import java.util.*;
  3. public class Main {
  4. static int n, m, idx;
  5. static int[] h, e, ne, color;
  6. public static void main(String[] args) {
  7. Scanner sc = new Scanner(System.in);
  8. n = sc.nextInt();
  9. m = sc.nextInt();
  10. h = new int[n + 1];
  11. Arrays.fill(h, -1);
  12. e = new int[2*m];
  13. ne = new int[2*m];
  14. color = new int[n + 1];
  15. while (m-- > 0) {
  16. int a, b;
  17. a = sc.nextInt();
  18. b = sc.nextInt();
  19. add(a, b);
  20. add(b, a);
  21. }
  22. boolean flag = true;
  23. for (int i = 1; i <= n; i++) {
  24. //第1个点还未被染色
  25. if (color[i] == 0) {
  26. //尝试将其染成1
  27. if (!dfs(i, 1)) {
  28. flag = false;
  29. break;
  30. }
  31. }
  32. }
  33. if (flag) System.out.println("Yes");
  34. else System.out.println("No");
  35. }
  36. static boolean dfs(int u, int c) {
  37. color[u] = c;
  38. for (int i = h[u]; i != -1; i = ne[i]) {
  39. //u当前临边为j
  40. int j = e[i];
  41. //如果j所在点为被染色,尝试将其染色
  42. if (color[j] == 0) {
  43. if (!dfs(j, 3 - c)) return false;
  44. }
  45. //如果j所在点已经被染色,判断下是否与c相同
  46. if (color[j] == c) return false;
  47. }
  48. return true;
  49. }
  50. static void add(int a, int b) {
  51. e[idx] = b;
  52. ne[idx] = h[a];
  53. h[a] = idx ++;
  54. }
  55. }
  1. //bfs
  2. import java.util.*;
  3. public class Main {
  4. static int n, m, idx;
  5. static int[] h, e, ne, color;
  6. public static void main(String[] args) {
  7. Scanner sc = new Scanner(System.in);
  8. n = sc.nextInt();
  9. m = sc.nextInt();
  10. h = new int[n + 1];
  11. Arrays.fill(h, -1);
  12. e = new int[2*m];
  13. ne = new int[2*m];
  14. color = new int[n + 1];
  15. while (m-- > 0) {
  16. int a, b;
  17. a = sc.nextInt();
  18. b = sc.nextInt();
  19. add(a, b);
  20. add(b, a);
  21. }
  22. boolean flag = true;
  23. for (int i = 1; i <= n; i++) {
  24. //第1个点还未被染色
  25. if (color[i] == 0) {
  26. //尝试将其染成1
  27. if (!bfs(i, 1)) {
  28. flag = false;
  29. break;
  30. }
  31. }
  32. }
  33. if (flag) System.out.println("Yes");
  34. else System.out.println("No");
  35. }
  36. static boolean bfs(int u, int c) {
  37. color[u] = c;
  38. Deque<Integer> q = new LinkedList<>();
  39. q.offer(u);
  40. while (!q.isEmpty()) {
  41. int cur = q.poll();
  42. c = 3 - color[cur];
  43. for (int i = h[cur]; i != -1; i = ne[i]) {
  44. int j = e[i];
  45. if (color[j] == 0) {
  46. color[j] = c;
  47. q.offer(j);
  48. } else if (color[j] != c)
  49. return false;
  50. }
  51. }
  52. return true;
  53. }
  54. static void add(int a, int b) {
  55. e[idx] = b;
  56. ne[idx] = h[a];
  57. h[a] = idx ++;
  58. }
  59. }
  1. //并查集
  2. import java.util.*;
  3. public class Main {
  4. static int n, m, idx;
  5. static int[] h, e, ne, color;
  6. public static void main(String[] args) {
  7. Scanner sc = new Scanner(System.in);
  8. n = sc.nextInt();
  9. m = sc.nextInt();
  10. h = new int[n + 1];
  11. Arrays.fill(h, -1);
  12. e = new int[2*m];
  13. ne = new int[2*m];
  14. color = new int[n + 1];
  15. while (m-- > 0) {
  16. int a, b;
  17. a = sc.nextInt();
  18. b = sc.nextInt();
  19. add(a, b);
  20. add(b, a);
  21. }
  22. for (int i = 1; i <= n; i++)
  23. color[i] = i;
  24. boolean flag = true;
  25. label: for (int i = 1; i <= n; i++) {
  26. if (h[i] == -1) continue; //当前点没有出边,孤立点直接跳过
  27. int first = e[h[i]];
  28. int c = find(color[i]);
  29. for (int k = h[i]; k != -1; k = ne[k]) {
  30. int j = e[k];
  31. if (find(j) == c) {
  32. flag = false;
  33. break label;
  34. }
  35. color[find(j)] = find(first);
  36. }
  37. }
  38. if (flag) System.out.println("Yes");
  39. else System.out.println("No");
  40. }
  41. static int find(int x) {
  42. return x == color[x] ? x : (color[x] = find(color[x]));
  43. }
  44. static void add(int a, int b) {
  45. e[idx] = b;
  46. ne[idx] = h[a];
  47. h[a] = idx ++;
  48. }
  49. }