染色法判定二分图
通过递归对各个点逐一染色,判断是否是二分图 。
基本代码
#include <iostream>
#include <cstring>
#include <vector>
const int MAXSIZE = 1e5+5;
int color[MAXSIZE]; // 储存每个点的染色情况 0 表示未染色, 1和2 分别表示两种不同的颜色
vector<int> G[MAXSIZE]; // 储存每个点相连的所有点
using std::vector;
void init() // 初始化数组
{
memset(color,0,sizeof(color));
memset(G,0,sizeof(G));
}
void read_data()
{
//scanf("%d",&n);
//......
//对每条读入的边应添加到G中
for(int i=0;i<n;i++)
{
scanf("%d%d",point1,point2);
G[point1].emplace_back(point2);
G[point2]/emplace_back(point1);
}
}
bool bipartite(int u) // 判断第u个点的染色方案是否可行
{
int len = G.size();
for(int i=0;i<len;i++) // 遍历u可以到达的所有点,逐一判断
{
int v = G[u][i];
if(color[u] == color[v]) return false; // 如果遍历到的点已经染过色了并且和他相连的点的颜色相同,那必不可能是二分图了(不符合定义了)
if(!color[v]) //没染过色的话就染色
{
color[v] = 3 - color[u]; //二分图,只用染两种颜色,分别用1,2表示。 如果前一个是1,那么当前应染色2,如果前一个是2,那么当前应染色1;
if(!bipartite(v)) return false; // 染完色后判断一下行不行。递归进去,以当前染色为基础继续染色,如果遇到不符合情况的说明不是二分图。(二分图一定能染色成功的)
}
}
return true; // 全部染色成功,说明是二分图,返回true
}
int main()
{
init();
read_data(); //读入数据
if(bipartite(0)) printf("是二分图\n");
else printf("不是二分图\n");
return 0;
}