当前位置: 首页 > news >正文

图论——二分图

二分图:
图中所有点可以分成两个点集,使得图中所有边都是在集合之间的,即,同一个集合内的点之间没有边。

1、所有二分图算法

在这里插入图片描述

2、染色法

用于判断一个图是否是二分图。
重要性质:一个图是二分图,当且仅当该图中不含奇数环(环中边数量是奇数)。

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 1e5 + 10, M = 2e5 + 10;

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

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

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])
        {
            if (!dfs(j, 3 - c)) return false;
        }
        else if (color[j] == c) return false;
    }
    return true;
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        add(a, b), add(b, a);
    }
    
    int flag = true;
    for (int i = 1; i <= n; i++)
        if (!color[i])
        {
            if (!dfs(i, 1))
            {
                flag = false;
            }
        }
    
    if (flag) cout << "Yes" << endl;
    else cout << "No" << endl;
    
    return 0;
}

考虑一个问题:

dfs里面把 if( !dfs(j, 3 - c) ) return false; 改成直接return dfs(j, 3 - c); 为什么不行?

注意下面两段代码的区别:
①
if ( !color[j] )
    if (!dfs(j , 3 - c))  return false;if ( !color[j] )
    return  dfs(j , 3 - c);

①只可能返回 false(或根本不返回),永远不会返回 true,即,只会在dfs失败的情况下返回主函数,dfs成功不会返回主函数。
而②可能返回 truefalse,即,dfs成功或失败都返回主函数。
对于dfs失败的情况,只要一个dfs失败,那这个图肯定不是二分图,不用继续遍历其他的邻点。
但对于dfs成功的情况,一个dfs染色的可能只是图中的一个连通块,一个连通块符合二分图并不代表整个图是二分图,所以不能直接返回true还要继续遍历其他的邻点,只有所有的dfs都是true,整个图才是二分图。

上面的话总结的普遍一点:
对于返回false的情况,只要局部返回false,那整体肯定是false的。但对于返回true的情况,局部返回 true并不代表整体也是true,所以不能直接根据局部的true就断定整体的true,还需要继续遍历,只有所有的局部都是true,整体才是true

3、匈牙利算法

给定一个二分图,求它的最大匹配。
实际运行时间一般远小于O(n*m)

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 510, M = 1e5 + 10;

int n1, n2, m;
int h[N], e[M], ne[M], idx;
int match[N];
bool st[N];

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

bool find(int x)
{
    for (int i = h[x]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true;
            if (match[j] == 0 || find(match[j]))
            {
                match[j] = x;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    cin >> n1 >> n2 >> m;
    
    memset(h, -1, sizeof h);
    
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        add(a, b);
    }
    
    int res = 0;
    for (int i = 1; i <= n1; i++)
    {
        memset(st, false, sizeof st);
        if (find(i)) res++;
    }
    
    cout << res << endl;
    
    return 0;
}

相关文章:

  • 面向对象程序设计———组合、委托 与 继承
  • C++设计模式
  • C++ 嵌套类
  • CMake指令解析 set(CMAKE_CXX_FLAGS “$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprec
  • 记一个测试sylar服务器日志模块时遇到的一个非常奇怪的问题
  • syscall()
  • 记一个编写宏时的错误
  • C++中全局变量,静态变量,静态局部变量 的初始化和内存分配问题
  • C++ 模板实现单例模式
  • 《C++ Primer》 异常
  • C++父类和子类指针的相互赋值和转换
  • 算法设计与分析————期末死亡冲刺
  • 现代软件工程————期末死亡冲刺
  • std::string::npos 常量解析
  • 练习4-3 求给定精度的简单交错序列部分和 (15 分)本题要求编写程序,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最后一项的绝对值不大于给定精度eps。
  • [译] React v16.8: 含有Hooks的版本
  • 【EOS】Cleos基础
  • express + mock 让前后台并行开发
  • Java比较器对数组,集合排序
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Linux快速复制或删除大量小文件
  • MYSQL 的 IF 函数
  • python docx文档转html页面
  • React-flux杂记
  • Vue.js-Day01
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 从零开始学习部署
  • 当SetTimeout遇到了字符串
  • 跨域
  • 力扣(LeetCode)21
  • 实现简单的正则表达式引擎
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 06-01 点餐小程序前台界面搭建
  • #FPGA(基础知识)
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (1) caustics\
  • (2.2w字)前端单元测试之Jest详解篇
  • (C++)八皇后问题
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (转)jdk与jre的区别
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET 设计一套高性能的弱事件机制
  • .Net6使用WebSocket与前端进行通信
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • // an array of int
  • /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
  • @requestBody写与不写的情况
  • @Transactional 详解
  • [ IO.File ] FileSystemWatcher
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • []C/C++读取串口接收到的数据程序