定理1、无向图G为二分图的充要条件: ①图G至少包含两个点 ②G中所有的回路的长度必须为偶数
根据这个定理,判断一个无向图是否为二分图的时候 只要判断该二分图是否存在奇圈。
常用的方法是相邻染色法,父节点和子节点染上不同的颜色,遇见相邻节点颜色相同,说明存在奇圈。
bfs实现:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <queue> 5 #define maxn 1010 6 using namespace std; 7 8 int n, m; 9 int col[maxn]; 10 int mp[maxn][maxn]; 11 bool isbg; 12 13 // bfs 判断是不是二分图 14 bool bfscol(int id) { 15 queue<int>que; 16 que.push(id); 17 col[id] = 1; 18 19 while (!que.empty()) { 20 int top = que.front(); 21 que.pop(); 22 for (int j=1; j<=n; ++j) { 23 if (mp[top][j]) { 24 if (col[j] == -1) { 25 col[j] = (col[top]^1); 26 que.push(j); 27 } 28 else if (col[j] == col[top]) { 29 return false; 30 } 31 } 32 } 33 } 34 return true; 35 } 36 37 int main() { 38 while(cin >> n >> m) { 39 memset(mp, 0, sizeof(mp)); 40 for (int i=0; i<m; ++i) { 41 int x, y; 42 cin >> x >> y; 43 mp[x][y] = 1; 44 mp[y][x] = 1; 45 } 46 47 isbg = true; 48 memset(col, -1, sizeof(col)); 49 50 for (int i=1; i<=n; ++i) { 51 if (col[i] != -1) continue; 52 else if (!bfscol(i)) { 53 isbg = false; 54 break; 55 } 56 } 57 58 if (!isbg) { 59 cout << "No\n"; 60 continue; 61 } 62 else cout << "Yes\n"; 63 } 64 return 0; 65 }
dfs实现:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #define maxn 1010 5 using namespace std; 6 7 int n, m; 8 int col[maxn]; 9 int mp[maxn][maxn]; 10 bool isbg; 11 12 // dfs 判断是否是二分图 13 void dfs_col(int i, int c) { 14 if (!isbg) return; // 剪枝 15 col[i] = c; 16 17 for (int j=1; j<=n; ++j) { 18 if (mp[i][j]) { // 所有相邻的点 19 if (col[j] == -1) { // 染上不同的颜色 20 dfs_col(j, c^1); 21 } 22 else if (col[j] == c) { // 如果相邻点颜色相同 不是二分图 23 isbg = false; 24 return; 25 } 26 } 27 } 28 return; 29 } 30 31 int main() { 32 while(cin >> n >> m) { 33 memset(mp, 0, sizeof(mp)); 34 for (int i=0; i<m; ++i) { 35 int x, y; 36 cin >> x >> y; 37 mp[x][y] = 1; 38 mp[y][x] = 1; 39 } 40 41 isbg = true; 42 memset(col, -1, sizeof(col)); 43 44 for (int i=1; i<=n; ++i) { 45 if (col[i] != -1) continue; 46 dfs_col(i, 1); 47 if (isbg == false) 48 break; 49 } 50 51 if (!isbg) { 52 cout << "No\n"; 53 continue; 54 } 55 else cout << "Yes\n"; 56 } 57 return 0; 58 }