二分圖又稱作二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,如果頂點V可分割為兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A, j in B),則稱圖G為一個二分圖。
二分圖的另一種等價的說法是,可以把每個節點着以黑色和白色之一,使得每條邊的兩個端點顏色不同.不難發現,非連通的圖是二分圖當且僅當每個連通分量都是二分圖,因此我們只考慮無向連通圖。
上圖就是一個二分圖
上圖不是個二分圖
那么我們如何去判斷一個圖是否是二分圖呢?
這里我們采取的是二分圖染色法:用兩種顏色,對所有頂點逐個染色,且相鄰頂點染不同的顏色,如果發現相鄰頂點染了同一種顏色,就認為此圖不為二分圖。 當所有頂點都被染色,且沒有發現同色的相鄰頂點,就退出
第一種寫法:DFS
1 #include <stdio.h> 2 #include <algorithm> 3 #include <iostream> 4 #include <stdbool.h> 5 #include <stdlib.h> 6 #include <string> 7 #include <string.h> 8 #include <math.h> 9 #include <vector> 10 #include <queue> 11 #include <stack> 12 #include <set> 13 #include <map> 14 15 #define INF 0x3f3f3f3f 16 #define LL long long 17 #define MAXN 1000010 18 using namespace std; 19 20 vector<int> graph[MAXN]; 21 int color[MAXN]; 22 int vis[MAXN]; 23 24 bool DFS(int u) 25 { 26 vis[u] = 1; 27 int len = graph[u].size(); 28 for (int j=0;j<len;j++) 29 { 30 int v = graph[u][j]; 31 if (vis[v] == 0) //如果沒有染色 32 { 33 color[v] = color[u]^1; 34 if (!DFS(v)) 35 return false; 36 } 37 else if (color[u]==color[v]) //如果已經染色,但是相連的兩點顏色相同 38 return false; 39 } 40 return true; 41 } 42 43 int main() 44 { 45 int T; 46 scanf("%d",&T); 47 while (T--) 48 { 49 int n,m; 50 scanf("%d%d",&n,&m); 51 memset(graph,0, sizeof(graph)); 52 for (int i=1;i<=m;i++) 53 { 54 int a,b; 55 scanf("%d%d",&a,&b); 56 graph[a].push_back(b); 57 graph[b].push_back(a); 58 } 59 memset(color,0, sizeof(color)); 60 memset(vis,0, sizeof(vis)); 61 int flag = true; 62 for (int i=1;i<=n;i++) 63 { 64 if (vis[i] == 0) 65 { 66 if (!DFS(i)) 67 { 68 flag = false; 69 break; 70 } 71 } 72 } 73 if (flag) 74 printf("Yes\n"); // 是二分圖 75 else 76 printf("No\n"); 77 } 78 }
第二種方法:BFS
1 #include <stdio.h> 2 #include <algorithm> 3 #include <iostream> 4 #include <stdbool.h> 5 #include <stdlib.h> 6 #include <string> 7 #include <string.h> 8 #include <math.h> 9 #include <vector> 10 #include <queue> 11 #include <stack> 12 #include <set> 13 #include <map> 14 15 #define INF 0x3f3f3f3f 16 #define LL long long 17 #define MAXN 100 18 using namespace std; 19 20 vector<int> graph[MAXN]; 21 int color[MAXN]; 22 23 24 bool BFS(int u) 25 { 26 queue<int> que; 27 que.push(u); 28 color[u] = 1; 29 while (!que.empty()) 30 { 31 int x = que.front(); 32 que.pop(); 33 for (int i=0;i<graph[x].size();i++) 34 { 35 int y = graph[x][i]; 36 if (color[y] == 0) 37 { 38 color[y] = color[x]^1; 39 que.push(y); 40 } 41 else 42 { 43 if (color[x] == color[y]) 44 return false; 45 } 46 } 47 } 48 return true; 49 } 50 51 int main() 52 { 53 int n,m; 54 cin >> n >> m; 55 for (int i=1;i<=m;i++) 56 { 57 int x,y; 58 cin >> x >> y; 59 graph[x].push_back(y); 60 graph[y].push_back(x); 61 } 62 memset(color,0, sizeof(color)); 63 //cout << BFS(1) << endl; 64 if (BFS(1)) 65 cout << "YES" << endl; 66 else 67 cout << "NO" << endl; 68 return 0; 69 }