ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

染色法判断二分图(加深对于DFS的理解于运用)

2021-02-17 13:00:59  阅读:217  来源: 互联网

标签:二分 递归 逻辑思维 int 染色 DFS color 染色法


染色法判定二分图

题目来源:acwing题库
题目地址:染色法判定二分图

题目描述:
给定一个n个点m条边的无向图,图中可能存在重边和自环。

请你判断这个图是否是二分图。

输入格式
第一行包含两个整数n和m。

接下来m行,每行包含两个整数u和v,表示点u和点v之间存在一条边。

输出格式
如果给定图是二分图,则输出“Yes”,否则输出“No”。

数据范围
1≤n,m≤105
输入样例:
4 4
1 3
1 4
2 3
2 4
输出样例:
Yes

这个题目的话主要就是对于DFS的运用和理解了,我作为一个初学者,是这么理解的,如果你单纯的以一个递归的角度去思考DFS的话,你会发现很难思考,因为它很复杂,循环中的递归。但是如果你以另外一种逻辑思维去思考的话,那么它就会变得通俗易懂。

比如这个题目,我们遍历图中的每一个点,如果这个点没有染色,那么我们将它染色,再通过这个点,寻找一下与它相邻的点,如果相邻的点没有染色,那就将其染色,如果寻找的过程中发现与其相邻的点中有颜色和其一样的点,那么发现错误,返回false,以此类推,就可以了。

有了上述的一个总体的逻辑思维,我们再通过这个逻辑思维去构造这个递归,就可以了。其实我们不需要知道具体的递归如何执行(当然了知道更好),我们只需要知道我们构造的递归符合我们的逻辑思维和我们的意愿即可,所以这对于刚刚入门的我帮助还是比较大的,这是一种全新的思维方式,即:对于某一种操作,我们并不需要知道其每一步的详细具体操作,我们只需要知道它的逻辑性以及正确性即可,具体的操作步骤可能会很复杂很复杂,但是只要它符合我们的逻辑以及正确就可以了。

所以我们在构造DFS的时候,要从逻辑思维的角度出发,而不是去死磕每一步应该如何做。

所以这篇文章的意义就在于提升我的理解与运用DFS的能力,获得一种全新的思维方式!!!

下面是AC代码+注释:

#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 200010;
int h[N], e[N], ne[N], idx = 0;
int color[N];
int n, m;
void connect(int a, int b)
{
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}
bool dfs(int x, int c)
{
    color[x] = c;//染色
    for (int i = h[x]; i != -1; i = ne[i])//遍历一下它所连接的所有点
    {
        if (!color[e[i]])//如果这个点没有被染色
        {
            if (!dfs(e[i], 3 - c))//那我们就把他染成另外一种颜色,如果过程中有错误,那么返回false;
                return false;
        }
        if (color[e[i]] == color[x])//如果相邻的两边颜色相等,那么就有问题,返回错误
            return false;
    }
    return true;//如果没有问题,返回true;
}
int main()
{
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    while (m--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        connect(a, b);
        connect(b, a);
    }
    bool flag = 1;//用于判断过程中是否出错
    for (int i = 1; i <= n; i++)//遍历一下所有的点,判断
    {
        if (!color[i])//如果这个点没有染色
        {
            if (!dfs(i, 1))//那么就把这个点染成1号色,如果过程中出现错误
            {
                flag = 0;
                break;
            }
        }
    }
    if (flag)printf("Yes");
    else printf("No");
    return 0;
}

碰到一些重要的而且好的知识点或者是思维方式,一定要及时记录下来以便复习的时候利用。

好了,每篇博客后面都附上一句话。

你没有回我信息,我也再也没有给你发信息,但是我知道我们并没有结束。

标签:二分,递归,逻辑思维,int,染色,DFS,color,染色法
来源: https://blog.csdn.net/weixin_52985599/article/details/113833105

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有