染色法
将所有点分成两个集合,使得所有边只出现在集合之间,就是二分图
二分图:一定不含有奇数环,可能包含长度为偶数的环, 不一定是连通图
dfs版本
代码思路:
染色可以使用1和2区分不同颜色,用0表示未染色
遍历所有点,每次将未染色的点进行dfs, 默认染成1或者2
由于某个点染色成功不代表整个图就是二分图,因此只有某个点染色失败才能立刻break/return
染色失败相当于存在相邻的2个点染了相同的颜色
#include
#include
#include

using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10; // 由于是无向图, 顶点数最大是N,那么边数M最大是顶点数的2倍
int e[M], ne[M], h[N], idx;
int st[N];

void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

bool dfs(int u, int color) {
st[u] = color;

for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(!st[j]) {if(!dfs(j, 3 - color)) return false;}else if(st[j] == color) return false;
}return true;

}

int main(){
int n, m;
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);  // 无向图,a->b, b->a
}bool flag = true;
for(int i = 1; i <= n; i ++){if(!st[i]){if(!dfs(i, 1)){flag = false;break;}}
}if(flag) puts("Yes");
else puts("No");
return 0;

}
bfs版本
代码思路
颜色 1 和 2 表示不同颜色, 0 表示 未染色
定义queue是存PII,表示 <点编号, 颜色>,
同理,遍历所有点, 将未染色的点都进行bfs
队列初始化将第i个点入队, 默认颜色可以是1或2
while (队列不空)
每次获取队头t, 并遍历队头t的所有邻边
若邻边的点未染色则染上与队头t相反的颜色,并添加到队列
若邻边的点已经染色且与队头t的颜色相同, 则返回false
C++ 代码
#include
#include
#include

using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;
typedef pair<int, int> PII;

int e[M], ne[M], h[N], idx;
int n, m;
int st[N];

void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

bool bfs(int u){
int hh = 0, tt = 0;
PII q[N];
q[0] = {u, 1};
st[u] = 1;

while(hh <= tt){auto t = q[hh ++];int ver = t.first, c = t.second;for (int i = h[ver]; i != -1; i = ne[i]){int j = e[i];if(!st[j]){st[j] = 3 - c;q[++ tt] = {j, 3 - c};}else if(st[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);
}int flag = true;
for(int i = 1; i <= n; i ++) {if (!st[i]){if(!bfs(i)){flag = false;break;}}
}if (flag) pu

什么叫二分图

有两顶点集且图中每条边的的两个顶点分别位于两个顶点集中,每个顶点集中没有边直接相连接!

说人话的定义:图中点通过移动能分成左右两部分,左侧的点只和右侧的点相连,右侧的点只和左侧的点相连。

下图就是个二分图:

下图不是个二分图:

如果判断一个图是不是二分图?

开始对任意一未染色的顶点染色。

判断其相邻的顶点中,若未染色则将其染上和相邻顶点不同的颜色。

若已经染色且颜色和相邻顶点的颜色相同则说明不是二分图,若颜色不同则继续判断。

bfs和dfs可以搞定!

#include
#include
#include

using namespace std;

const int N = 100010 * 2;
int e[N], ne[N], idx;//邻接表存储图
int h[N];
int color[N];//保存各个点的颜色,0 未染色,1 是红色,2 是黑色
int n, m;//点和边

void add(int a, int b)//邻接表插入点和边
{
e[idx] = b, ne[idx]= h[a], h[a] = idx++;
}

bool dfs(int u, int c)//深度优先遍历
{
color[u] = c;//u的点成 c 染色

//遍历和 u 相邻的点
for(int i = h[u]; i!= -1; i = ne[i])
{int b = e[i];                   if(!color[b])//相邻的点没有颜色,则递归处理这个相邻点{if(!dfs(b, 3 - c)) return false;//(3 - 1 = 2, 如果 u 的颜色是2,则和 u 相邻的染成 1)//(3 - 2 = 1, 如果 u 的颜色是1,则和 u 相邻的染成 2)}else if(color[b] && color[b] != 3 - c)//如果已经染色,判断颜色是否为 3 - c{                                     return false;//如果不是,说明冲突,返回                   }
}
return true;

}

int main()
{
memset(h, -1, sizeof h);//初始化邻接表
cin >> n >> m;
for(int i = 1; i <= m; i++)//读入边
{
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
for(int i = 1; i <= n; i++)//遍历点
{
if(!color[i])//如果没染色
{
if(!dfs(i, 1))//染色该点,并递归处理和它相邻的点
{
cout << “No” << endl;//出现矛盾,输出NO
return 0;
}

    }
}
cout << "Yes" << endl;//全部染色完成,没有矛盾,输出YES
return 0;

}

染色法判定二分图的算法相关推荐

  1. 染色法判定二分图 匈牙利算法

    染色法判定二分图 思路:相邻的点染不同颜色 看能不能染完 如果过程中出现相邻点相同颜色,就不可以 注意:需要遍历n个点 看此点是否被染色过 如果没有就进行一次dfs或bfs 二分图:可以把点分成两个集 ...

  2. AcWing 860. 染色法判定二分图 (染色法)

    题目链接 : 点击查看 题目描述 : 给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环. 请你判断这个图是否是二分图. 输入输出格式 : 输入 第一行包含两个整数 n 和 m. 接下来 m ...

  3. AcWing 860. 染色法判定二分图(染色法)

    题目连接 https://www.acwing.com/problem/content/862/ 思路 我们对每一个节点进行染色操作,我们需要注意的是我们染色后要将当前节点的所有相邻节点全部染成另一种 ...

  4. 【染色法判别二分图】

    模板题: AcWing 860. 染色法判定二分图 解题思路: (1)判断一个图是否是二分图,判断是否存在奇数环即可,用染色法判断即可. (2)二分图: 是指可以将点集分成两半,每个集合内都没有边,但 ...

  5. hdu 5285(染色法判断二分图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5285 解题思路:很明显的是二分图的判定,用染色法即可. 不过这题有一个坑,当n<=1和m=0时要 ...

  6. NYOJ1015 二部图(染色法判断二分图)

    描述 二部图又叫二分图,我们不是求它的二分图最大匹配,也不是完美匹配,也不是多重匹配,而是证明一个图是不是二部图.证明二部图可以用着色来解决,即我们可以用两种颜色去涂一个图,使的任意相连的两个顶点颜色 ...

  7. 图论 —— 染色法判断二分图

    二分图定义 二分图,又称二部图,英文名叫 Bipartite graph. 二分图是什么?节点由两个集合组成,且两个集合内部没有边的图.换言之,存在一种方案,将节点划分成满足以上性质的两个集合. 二分 ...

  8. ~~染色法判别二分图

    时间复杂度是 O(n+m), n 表示点数,m 表示边数 int n; // n表示点数 int h[N], e[M], ne[M], idx; // 邻接表存储图 int color[N]; // ...

  9. E. Split Into Two Sets(染色法判断二分图)

    Problem - 1702E - Codeforces 波利卡普最近得到了一组n(数字n-偶数)的骨牌.每块多米诺骨牌包含1到n的两个整数. 他能把所有的骨牌分成两组,使每组骨牌上的数字都不一样吗? ...

  10. 常用代码模板3——搜索与图论(Bellman-Ford算法 、spfa 算法、floyd算法、Kruskal算法、染色法、匈牙利算法 )

    目录 一.树与图的存储 二.树与图的遍历 (1) 深度优先遍历 -- 模板题 AcWing 846. 树的重心 (2) 宽度优先遍历 -- 模板题 AcWing 847. 图中点的层次 拓扑排序 -- ...

最新文章

  1. 谷歌母公司投资成绩:4大机构各有侧重,投资2个马斯克项目
  2. 庆祝一下,基于JXTA的P2P文件共享传输文件测试成功。
  3. 为什么在重庆比北京更容易迷路?Nature子刊:大脑GPS系统呈蜂窝状,弯路多了就“变形”...
  4. BPI:bit for Webduino WEB:Bit 教育版平台正式发布,支持离线安装使用
  5. 2017网易校招真题 合唱团
  6. Linux 环境下/etc/profile和/etc/profile.d 的区别和用法!
  7. Linux lvs 多端口组成
  8. 分布式一致性算法Raft简介(上)
  9. java解析json_JAVA解析JSON数据
  10. java集合——遗留的集合
  11. VMware 安装kali——linux
  12. centos7 centos-home 磁盘空间转移至centos-root下(磁盘空间不足,磁盘不足)
  13. python 脚本编码_Python-我如何编码我的Python脚本
  14. 教你在Windows轻松修改Hosts文件
  15. python 简易计算器
  16. 网络调试助手无法连接tcp服务器,W5500 TCP 客户端网络调试助手连不上
  17. JSON树转换成线性列表(python)
  18. 数学建模中数据处理类型题目的主要处理流程与方法
  19. evc小项目:Gps功分器测试
  20. json序列化 java对象_Json 数据反序列化为Java对象

热门文章

  1. 原生的APP、小程序(微信小程序、支付宝小程序、头条小程序、百度小程序.等等)、H5 的优势与劣势分析有那些?
  2. 央央家政解读:育儿嫂服务内容和标准
  3. ROS之launch文件解析
  4. MapReduce名词解释
  5. 信息安全快讯丨叶落知秋,e讯知安全
  6. 初中英语语法(015)-附加疑问句
  7. jQuery 3D图片切换动画
  8. 在线文件管理html,KODExplorer可道云-开源Web在线文件管理系统
  9. 8002雨过天晴等冠号
  10. 支持2018的ibm服务器,联想支持Win10 2018年4月更新(RS4版本1803)的机型