判断一个无向图是不是二分图,使用染色法.对每个顶点的相邻顶点染与顶点不同的颜色。如果染过色且与顶点颜色相同,则不是二分图。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 202;
vector<int>mp[maxn];
int color[maxn];
bool bfs(int s)
{
color[s] = 0; //连通分支的起点可以染1也可以染0
queue<int>q;
q.push(s);
while (!q.empty())
{
s = q.front();
q.pop();
for (int i = 0; i < (int)mp[s].size(); i ++) {
int t = mp[s][i];
if (color[t] == -1) color[t] = !color[s], q.push(t); //如果相邻顶点未被染色,则加入
//队列。
if (color[t] == color[s]) { //如果相邻顶点染相同颜色,则不是二分图。
return false;
}
}
}
return true;
}
int main()
{
int n, m;
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; i ++) mp[i].clear();
memset(color, -1, (n+1)*sizeof(color[0]));
for (int i = 0; i < m; i ++) {
int x, y;
cin >> x>>y;
mp[x].push_back(y); //无向图存储两条边
mp[y].push_back(x);
}
int flag = true; //初始化无向图是二分图
for (int i = 1; i <= n; i ++) {
if (color[i] == -1 && !bfs(i)) { //对每个连通分支染色,如果两个相邻的点
//颜色相同,则不是二分图。
flag = false;
break;
}
}
if (!flag) cout <<"no"<<endl;
else
cout <<"yes"<<endl;
}
return 0;
}
4 4 1 2 1 3 1 4 2 3 6 5 1 2 1 3 1 4 2 5 3 6
No 3
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 202;
vector<int>mp[maxn];
int color[maxn];
int matchx[maxn];
int matchy[maxn];
bool vis[maxn];
bool bfs(int s)
{
color[s] = 0; //连通分支的起点可以染1也可以染0
queue<int>q;
q.push(s);
while (!q.empty())
{
s = q.front();
q.pop();
for (int i = 0; i < (int)mp[s].size(); i ++) {
int t = mp[s][i];
if (color[t] == -1) color[t] = !color[s], q.push(t); //如果相邻顶点未被染色,则加入
//队列。
if (color[t] == color[s]) { //如果相邻顶点染相同颜色,则不是二分图。
return false;
}
}
}
return true;
}
bool dfs(const int& x, const int& n)
{
for (int i = 0; i < (int)mp[x].size(); i ++) {
int j = mp[x][i];
if (vis[j] == false) {
vis[j] = true;
if (matchy[j] == -1 || dfs(matchy[j], n)) {
matchy[j] = x;
matchx[x] = j;
return true;
}
}
}
return false;
}
int work(const int& n)
{
int res = 0;
memset(matchx, -1, (n+1)*sizeof(matchx[0]));
memset(matchy, -1, (n+1)*sizeof(matchy[0]));
for (int i = 1; i <= n; i ++) {
memset(vis, 0, (n+1)*sizeof(vis[0]));
if (matchx[i] == -1 && dfs(i, n)) res ++;
}
return res;
}
int main()
{
int n, m;
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; i ++) mp[i].clear();
memset(color, -1, (n+1)*sizeof(color[0]));
for (int i = 0; i < m; i ++) {
int x, y;
cin >> x>>y;
mp[x].push_back(y); //无向图存储两条边
mp[y].push_back(x);
}
int flag = true; //初始化无向图是二分图
for (int i = 1; i <= n; i ++) {
if (color[i] == -1 && !bfs(i)) { //对每个连通分支染色,如果两个相邻的点
//颜色相同,则不是二分图。
flag = false;
break;
}
}
if (!flag) {puts("No"); continue;}
int res = work(n);
printf("%d\n", res/2);
}
return 0;
}
原文:http://blog.csdn.net/wuhuajunbao/article/details/41775341