性质:一个图是二分图,当且仅当图中不含奇数环
奇数环:环中边的数量是奇数
二分图:我们能把所有点分为两边,集合内部是没有边的
这个图能被2染色
染色法:一条边的端点颜色不同
由于图中不含奇数环,这个染色过程中一定是没有矛盾的
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 200010; 4 int h[N], e[N], ne[N], idx; 5 int color[N]; 6 int n, m; 7 void add(int a, int b) { 8 e[idx] = b; 9 ne[idx] = h[a]; 10 h[a] = idx++; 11 } 12 bool dfs(int u, int c) { //将u点染为c色 13 color[u] = c; 14 for (int i = h[u]; i != -1; i = ne[i]) { //遍历每个点 15 int j = e[i]; 16 if (!color[j]) { //如果这个点没被染色 17 if (!dfs(j, 3 - c)) { //染成另外一种颜色 18 return false; 19 } 20 } else if (color[j] == c) { //相同,false 21 return false; 22 } 23 } 24 return true; 25 } 26 int main() { 27 memset(h, -1, sizeof h); 28 cin >> n >> m; 29 while (m--) { 30 int a, b; 31 cin >> a >> b; 32 add(a, b); 33 add(b, a); 34 } 35 bool f = true; 36 for (int i = 1; i <= n; i++) { 37 if (!color[i]) { //如果这个点没被染色 38 if (!dfs(i, 1)) { //如果返回了false 39 f = false; 40 break; 41 } 42 } 43 } 44 if (f) { 45 cout << "Yes" << endl; 46 } else { 47 cout << "No" << endl; 48 } 49 return 0; 50 }