染色法判定二分图

题目传送门

将所有点分成两个集合,使得所有边只出现在集合之间,就是二分图。

那成为二分图的必要条件是什么呢?就是图里不能含有奇数环。为什么呢?我们来看一张图

这时有一个结点就不知道改属于哪个集合,所以二分图里不能有奇数环,接下来就看一下如何用染色法判二分图。

具体思路

首先我们当遍历到一个结点没有被染色(就是没有确定在哪一个集合),我们就要进行进行dfs,先看一下两个参数吧:

  1. u 表示结点编号
  2. c 表示我们要染的颜色

然后我们先把颜色存起来,然后遍历这个点连通的点,每次用一个变量 j 存储当前点的编号,如果遍历到的点没有染过色,就递归染色,如果是 原来是 1 就变成 2 以此类推,我们设 color 为当前点的颜色,那么 3color 就是我们要弄的新颜色。

最后还要判断这个点的颜色是否和原来的颜色是否一样,一样就不行了。

code

#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5 + 10,M = 2e5 + 10; int n,m; int h[N], e[M], ne[M], idx; int color[N]; void add(int a, int b) // 添加一条边a->b { e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ; } bool dfs(int u, int c) { color[u] = c; for(int i = h[u]; i != -1; i = ne[i]) { int j = e[i];// 存储当前点的编号 if(!color[j]) { if(!dfs(j,3 - c))return false; //1变为2,2变为1 } else if(color[j] == c) return false;//颜色不能相同,"一山不容二虎" } return true; } int main() { scanf("%d%d", &n, &m); memset(h, -1, sizeof h); while(m -- ) { int a, b; scanf("%d%d", &a, &b); add(a, b), add(b, a); } bool flag = true; for (int i = 1; i <= n; i ++ ) if(!color[i]) { if(!dfs(i, 1)) { flag = false; break; } } if(flag) puts("Yes"); else puts("No"); return 0; }

__EOF__

本文作者ljfyyds
本文链接https://www.cnblogs.com/ljfyyds/p/16517281.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ljfyyds  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示