一、
二分图基础:
参考链接:https://blog.csdn.net/jeryjeryjery/article/details/79596922
https://www.cnblogs.com/penseur/archive/2013/06/16/3138981.html
什么叫二分图:给你一些点,其中这些点之间的某两个点是相连的。如果你可以把全部点分成两个集合 且 每个集合的任意两个点之间没有连线
也就是说对于任意一条边它的两个点不能来自于一个集合,就比如:
1,2,3一个集合,其他点一个集合就是二分图!
染色法判断是否为一个二分图:https://blog.csdn.net/li13168690086/article/details/81506044
算法过程:用两种颜色,对所有顶点逐个染色,且相邻顶点染不同的颜色,如果发现相邻顶点染了同一种颜色,就认为此图不为二分图。 当所有顶点都 被染色,且没有发现同色的相邻顶点,就退出。
以NYOJ 1015 二部图为例题:
代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <stdio.h> 5 #include <math.h> 6 using namespace std; 7 const int N = 505; 8 int m,n; 9 int color[N]; 10 int edge[N][N]; 11 bool dfs(int v, int c){ 12 color[v] = c; //将当前顶点涂色 13 for(int i = 0; i < n; i++){ //遍历所有相邻顶点,即连着的点 14 if(edge[v][i] == 1){ //如果顶点存在 15 if(color[i] == c) //如果颜色重复,就返回false 16 return false; 17 if(color[i] == 0 && !dfs(i,-c)) //如果还未涂色,就染上相反的颜色-c,并dfs这个顶点,进入下一层 18 return false; //返回false 19 } 20 } 21 return true; //如果所有顶点涂完色,并且没有出现同色的相邻顶点,就返回true 22 } 23 void solve(){ 24 for(int i = 0; i < n; i++){ 25 if(color[i] == 0){ 26 if(!dfs(i, 1)){ 27 printf("NOT BICOLORABLE.\n"); 28 return; 29 } 30 } 31 } 32 printf("BICOLORABLE.\n"); 33 } 34 int main(){ 35 int u,v; 36 while(cin >> n >> m){ 37 memset(color, 0, sizeof(color)); 38 memset(edge, 0, sizeof(edge)); 39 for(int i = 0; i < m; i++){ 40 cin >> u >> v; //因为是无向图,所以要往两个方向添加边 41 edge[u][v] = 1; //正着添加 42 edge[v][u] = 1; //反着添加 43 } 44 solve(); 45 } 46 return 0; 47 }