二分圖的定義及判斷


二分圖又稱作二部圖,是圖論中的一種特殊模型。 設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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM