• acwing算法基础之搜索与图论--染色法判断二分图


    1 基础知识

    二分图:每条边连接的起点和终点,分别属于集合A和集合B。

    一个图是二分图,当且仅当,图中不含奇数环(即,回环中的结点数目是奇数)。

    染色法判定二分图的关键步骤为:

    1. 初始化颜色数组color[1~n] = 0。
    2. 遍历每一个结点a:如果它没有被染色,将其染色为1,即dfs(a, 1)。
    3. 如果没有矛盾,则说明该图是二分图,否则,不是。
    bool dfs(int x, int c) {
    	color[a] = c;
    	//递归处理它的子结点
    	for (auto b : g[a]) {
    		if (!color[b]) {
    			if (!dfs(b, 3 - c)) return false; 
    		} else {
    			if (color[b] == c) return false;
    		}
    	}
    	return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2 模板

    int n;      // n表示点数
    int h[N], e[M], ne[M], idx;     // 邻接表存储图
    int color[N];       // 表示每个点的颜色,-1表示未染色,0表示白色,1表示黑色
    
    // 参数:u表示当前节点,c表示当前点的颜色
    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] == -1)
            {
                if (!dfs(j, !c)) return false;
            }
            else if (color[j] == c) return false;
        }
    
        return true;
    }
    
    bool check()
    {
        memset(color, -1, sizeof color);
        bool flag = true;
        for (int i = 1; i <= n; i ++ )
            if (color[i] == -1)
                if (!dfs(i, 0))
                {
                    flag = false;
                    break;
                }
        return flag;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3 工程化

    题目1:请判断该图是否为二分图。

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 1e5 + 10;
    int n, m;
    vector<vector<int>> g(N);
    int color[N];
    
    bool dfs(int a, int c) {
        color[a] = c;
        
        //看结点a能走到哪儿
        for (auto b : g[a]) {
            if (!color[b] && !dfs(b, 3 - c)) return false;
            if (color[b] && color[b] == c) return false;
        }
        return true;
    }
    
    int main() {
        cin >> n >> m;
        int a, b;
        while (m--) {
            cin >> a >> b;
            g[a].emplace_back(b);
            g[b].emplace_back(a);
        }
        
        bool flag = true;
        for (int i = 1; i <= n; ++i) {
            if (!color[i] && !dfs(i, 1)) {
                flag = false;
                break;
            }
        }
        
        if (flag) {
            cout << "Yes" << endl;
        } else {
            cout << "No" << endl;
        }
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
  • 相关阅读:
    nexus配置管理docker镜像
    黑马旅游网_项目学习_1_orcle数据库建表
    Django5+React18前后端分离开发实战05 序列化
    【笔试强训】Day 5
    使用docker搭建ELK进行日志收集
    javascript 深浅拷贝
    Qt源码阅读(一) 信号槽的连接与调用
    前端总结——React的通信方式
    Python类变量和实例变量(类属性和实例属性)
    SAP中由删除合同项目导致的价格条件无法修改问题
  • 原文地址:https://blog.csdn.net/YMWM_/article/details/134355733