判断一个无向图是不是二分图,使用染色法.对每个顶点的相邻顶点染与顶点不同的颜色。如果染过色且与顶点颜色相同,则不是二分图。
#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