描述
二部图又叫二分图,我们不是求它的二分图最大匹配,也不是完美匹配,也不是多重匹配,而是证明一个图是不是二部图。证明二部图可以用着色来解决,即我们可以用两种颜色去涂一个图,使的任意相连的两个顶点颜色不相同,切任意两个结点之间最多一条边。为了简化问题,我们每次都从0节点开始涂色
输入
多组数据 第一行一个整数 n(n<=200) 表示 n个节点 第二行一个整数m 表示 条边 随后 m行 两个整数 u , v 表示 一条边
输出
如果是二部图输出 BICOLORABLE.否则输出 NOT BICOLORABLE.
样例输入
3
3
0 1
1 2
2 0
3
2
0 1
0 2
样例输出
NOT BICOLORABLE.
BICOLORABLE.
思路
定义:一个无向图G是二部图当且仅当G中无奇数长度的回路
二分图相关:二分图的最大匹配、完美匹配和匈牙利算法
我们利用染色法来判断一个图是不是二分图,先找一个点为起点,然后把与它相连的点的颜色都变成与它相反的颜色,然后把这些点加入到队列中,如果这些点的颜色与父节点的不一样,就忽略,如果一样就证明了这个图不是二分图
代码
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<iostream>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 10000007
#define debug() puts("what the fuck!!!")
#define ll longlong
using namespace std;
const int N=200+20;
vector<int> G[N];
int color[N];
int dfs()
{
queue<int>q;
q.push(0);
color[0]=1;
while(!q.empty())
{
int v1=q.front();
q.pop();
for(int i=0; i<G[v1].size(); i++)
{
int v2=G[v1][i];
if(color[v2]==-1)
{
color[v2]=-color[v1];
q.push(v2);
}
else if(color[v1]==color[v2])
return 0;
}
}
return 1;
}
int main()
{
int n,m,a,b;
while(~scanf("%d",&n))
{
for(int i=0; i<N; i++)G[i].clear();
mem(color,-1);
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
}
if(dfs())
puts("BICOLORABLE.");
else
puts("NOT BICOLORABLE.");
}
return 0;
}