算法学习笔记(二分图染色)

首先我们需要明确什么是二分图:如果无向图 G = ( V , E ) G = (V, E) G=(V,E)的所有点可以分为两个集合 V 1 、 V 2 V_1、V_2 V1V2,所有的边都在 V 1 V_1 V1 V 2 V_2 V2之间,而 V 1 V_1 V1 V 2 V_2 V2的内部没有边,称 G G G是一个二分图。

直接说结论:如果一个图是二分图,那么它一定没有边数量为奇数的环。

判断一个图是否为二分图,一般用“染色法”进行判断。

用两种颜色对所有点进行染色,要求处在一条边上的两个点的颜色不能相同,染色结束后,如果没有相邻点颜色相同,那就是二分图。

例题;【模板】二分图判定

题目描述

给定一个 n n n m m m边的无向图,请判定它是否是一个二分图。

如果是,输出 " Y E S " "YES" "YES",反之输出 " N O " "NO" "NO"

输入描述

第一行三个整数 n n n, m m m ( 1 ≤ n , m ≤ 2 × 1 0 5 ) (1 \leq n,m \leq 2 \times 10^5) (1n,m2×105)

接下来 m m m行,每行两个整数 x , y x,y x,y表示一条无向边。 ( 1 ≤ x , y ≤ n , x ≠ y ) (1 \leq x,y \leq n,x \not = y) (1x,yn,x=y)

输出描述

一行输出结果。

输入样例1

4 4
1 2 
2 3
3 1
1 4

输出样例1

NO

输入样例2

4 4
1 2 
2 3
3 4
1 4

输出样例2

YES

染色法使用 d f s dfs dfs实现,下边给出带注释代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 9;

int n, m;
vector<int> g[N];
int col[N];     //存储颜色,-1表示未染色,0、1表示颜色

bool dfs(int x) //染色
{
    for(const auto &y : g[x])       //遍历所有边
    {
        if(col[y] == -1)            //如果没被染色
        {
            col[y] = col[x] ^ 1;    //染上不同颜色

            //下一个节点染不上色就返回flase,将flase传到main函数
            if(!dfs(y)) return false;
        }
        else if(col[y] == col[x]) return false;     //如果已经被染色但是和该节点颜色相同,也返回false
    }
    return true;
}

void solve()
{
    cin >> n >> m;

    //存图
    for(int i = 1; i <= m; ++i)
    {
        int x, y; cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }

    //初始化
    for(int i = 1; i <= n; ++i) col[i] = -1;
    
    int ans = 1;
    for(int i = 1; i <= n; ++i)
    {
        if(col[i] == -1)
        {
            //用与运算只要有一个没染色答案就变成0
            ans &= dfs(i); 
        }
    }

    cout << (ans ? "YES" : "NO") << '\n';
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _ = 1;
    while(_--) solve();
    return 0;
}

注意初始化!!!注意初始化!!!注意初始化!!!

  • 33
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 算法个人学习笔记pdf是一种以电子文档形式呈现的算法学习笔记资源。在这个pdf中,个人学习者可以记录和整理自己在学习算法过程中的思考、心得和解题方法。在这个学习笔记pdf中,个人学习者可以自由地添加和编辑自己的学习内容,包括算法的原理、算法实现的代码以及相应的思路和分析。通过这种方式,个人学习者可以更系统地学习和理解算法,并且能够随时查看自己的学习进展和学习成果。 通过编写和整理算法个人学习笔记pdf,个人学习者可以更好地理解和应用学习到的算法知识。这种记录和整理的过程可以帮助个人学习者更深入地思考问题和解决问题的方法,同时也可以帮助个人学习者更好地复习和回顾已学习算法知识。 对于其他学习者来说,算法个人学习笔记pdf也是一个宝贵的学习资源。其他学习者可以通过查阅个人学习者的学习笔记pdf,借鉴和学习其中的思路和方法。这样可以帮助其他学习者更好地理解和应用算法知识,同时也可以促进知识的分享和交流。 总的来说,算法个人学习笔记pdf是一个为个人学习者提供记录和整理学习过程的工具,同时也是一个为其他学习者提供学习资源和参考的媒介。通过编写和整理算法个人学习笔记pdf,个人学习者可以更好地学习和理解算法知识,同时也可以促进算法知识的分享和交流。 ### 回答2: 算法个人学习笔记pdf是一份记录个人学习算法的文档,具有以下特点和优势。 首先,这份学习笔记是以PDF格式保存的,这意味着可以在任何设备上方便地查看和阅读,无需依赖特定的平台或软件。无论是在电脑、平板还是手机上,都可以轻松地浏览和学习。 其次,这份学习笔记是个人整理的,因此具有个性化的特点。不同的人在学习算法时可能会关注和理解的重点有所不同,通过个人学习笔记,可以反映出个人对算法知识的理解和思考。这样的学习笔记对于个人的学习和复习过程非常有帮助。 此外,这份学习笔记应当具有清晰的结构和逻辑。算法知识通常是有层次结构的,基本的知识点和概念通常是必须掌握的基础,而进阶的知识则需要在掌握基础知识的基础上构建。学习笔记应当按照这个结构和逻辑进行组织,便于学习者理解和掌握。 最后,这份学习笔记应当具有实例和练习题。算法知识的学习不能仅仅停留在理论层面,还需要通过实际的例子和练习题进行实践和巩固。学习笔记应当包含这些实例和练习题,并给出相应的解析和答案,方便学习者进行练习和巩固。 总而言之,算法个人学习笔记pdf是一份方便、个性化、结构清晰、包含实例和练习题的文档,对于学习者来说非常有价值。 ### 回答3: 算法学习笔记PDF是一份用于记录个人学习算法的文档。通过编写学习笔记,我可以对算法的理论和实践有更深入的理解和掌握。 首先,在学习算法的过程中,理论与实践结合是非常重要的。在学习笔记中,我可以记录下算法的原理和相关的数学推导,以及对应的代码实现和应用场景。通过这样的记录方式,我可以更好地理解算法的本质和使用方式。 其次,学习笔记可以帮助我回顾和巩固所学的知识。通过整理和总结学习笔记,我可以梳理出算法的基础知识和重要思想,并将其记忆固定下来。同时,学习笔记也可以作为复习的资料,提供方便快捷的回顾方式。 此外,学习笔记还可以促进自我思考和学习方法的改进。在编写笔记的过程中,我可以思考和提出自己的问题,并通过查阅相关资料和与他人讨论,来找到问题的答案和解决方案。这样的思考过程可以帮助我提高问题解决的能力和学习效果。 最后,学习笔记可以与他人分享和交流。通过分享学习笔记,我可以与其他学习者进行交流和讨论,互相学习和提高。同时,学习笔记也可以作为自己学习和成长的见证,激励自己坚持学习和进步。 总之,算法个人学习笔记PDF是一份记录、回顾、思考和分享的文档,对于个人的算法学习具有重要的意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值