二分图又称作二部图,是图论中的一种特殊模型。 设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 "); // 是二分图 75 else 76 printf("No "); 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 }