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

目录

  • [1 基础知识](#1 基础知识)
  • [2 模板](#2 模板)
  • [3 工程化](#3 工程化)

1 基础知识

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

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

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

  1. 初始化颜色数组color[1~n] = 0。
  2. 遍历每一个结点a:如果它没有被染色,将其染色为1,即dfs(a, 1)。
  3. 如果没有矛盾,则说明该图是二分图,否则,不是。
cpp 复制代码
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;
}

2 模板

cpp 复制代码
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;
}

3 工程化

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

cpp 复制代码
#include <iostream>
#include <cstring>
#include <vector>

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;
}
相关推荐
数研小生7 小时前
构建命令行单词记忆工具:JSON 词库与艾宾浩斯复习算法的完美结合
算法·json
芒克芒克7 小时前
LeetCode 题解:除自身以外数组的乘积
算法·leetcode
Python 老手7 小时前
Python while 循环 极简核心讲解
java·python·算法
@Aurora.7 小时前
优选算法【专题九:哈希表】
算法·哈希算法·散列表
爱看科技8 小时前
微美全息(NASDAQ:WIMI)研究拜占庭容错联邦学习算法,数据安全与隐私保护的双重保障
算法
qq_417129258 小时前
C++中的桥接模式变体
开发语言·c++·算法
YuTaoShao8 小时前
【LeetCode 每日一题】3010. 将数组分成最小总代价的子数组 I——(解法二)排序
算法·leetcode·排序算法
吴维炜10 小时前
「Python算法」计费引擎系统SKILL.md
python·算法·agent·skill.md·vb coding
Σίσυφος190011 小时前
PCL Point-to-Point ICP详解
人工智能·算法
玄〤11 小时前
Java 大数据量输入输出优化方案详解:从 Scanner 到手写快读(含漫画解析)
java·开发语言·笔记·算法