首页 > 编程语言 >二分图的判别(染色法、匈牙利算法)

二分图的判别(染色法、匈牙利算法)

时间:2024-10-24 22:32:38浏览次数:7  
标签:二分 return 判别 idx int ne 算法 add 染色法

二分图的判别:
首先二分图是指一个图如果没有奇数环,则该图是二分图。
其实这两种算法都是基于dfs来做的,要深刻理解每个算法的dfs指代的是什么。
1、染色法:所谓的染色是指所有边的每一条边的两个端点颜色不同,算法思路就是让每个顶点都做一次dfs,判断其中有无同一条边的端点颜色相同。

#include <bits/stdc++.h>
using namespace std;
const int N = 1010, M = 2020, INF = 0x3f3f3f;
int m, n;
int h[N], e[M], ne[M], idx; // 注意不是e[N]和ne[N]
int color[N];
int add(int a, int b)
{
   e[idx] = b, ne[idx] = h[a], h[a] = 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 >> m >> n;
   memset(h,-1,sizeof h);
   while (m--)
   {
      int a, b;
      cin >> a >> b;
      add(a, b), add(b, a);
   }
   bool flag = true;
   for (int i = 1; i <= n; i++)
   {
      if (!color[i])
      {
         if (!dfs(i, 1))
         {
            flag = false;
            break;
         }
      }
   }
   if (!flag)
      cout << "No" << endl;
   else
      cout << "Yes" << endl;
   return 0;
}

2、匈牙利算法:就是两个集合之间最多能匹配多少

#include <bits/stdc++.h>
using namespace std;

const int N = 101, M = 10020;
int n1, n2, m, res;         // n1表示第一个集合中的点数,n2表示第二个集合中的点数
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++;
}
bool find(int u)
{
   for (int i = h[u]; i != -1; i = ne[i])
   {
      if (!st[j])
      {
         int j = e[i];
         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);
   }
   // 求最大匹配数,依次枚举第一个集合中的每个点能否匹配第二个集合中的点
   for (int i = 1; i <= n1; i++)
   {
      memset(st, flase, sizeof st);
      if (find(i))
         res++;
   }
   cout << res << endl;
   return 0;
}

标签:二分,return,判别,idx,int,ne,算法,add,染色法
From: https://www.cnblogs.com/Minyou03/p/18501435

相关文章

  • wqs二分
    感觉一般可能要严谨证明的话还是有点麻烦,不如直接打表,或者先老实WA一发来的快一般题目会有选恰好k个/次这样的限制大致就是通过二分斜率,然后通过dp,或者贪心计算出最大/最小值,然后通过判断这个最大/最小值对应的选的个数来调整需要注意的是,我们计算的相当于是截距,还要+/-kl才......
  • P2839 [国家集训队] middle(二分+可持久化线段树)
    P2839[国家集训队]middle二分+可持久化线段树中位数经典做法,二分答案,将小于的部分看做\(-1\),大于等于的部分看做\(+1\),那么答案可以更大的条件就是区间和大于等于\(0\)(等于\(0\)可不可以取到看是下取整还是上取整,本题是上取整)。那么问题就是怎么判断有没有这样一个区间......
  • 首个统一生成和判别任务的条件生成模型框架BiGR:专注于增强生成和表示能力,可执行视觉生
    BiGR是一种新型的图像生成模型,它可以生成高质量的图像,同时还能有效地提取图像特征。该方法是通过将图像转换为一系列的二进制代码来工作,这些代码就像是图像的“压缩版”。在训练时会遮住一些代码,然后让模型学习如何根据剩下的代码来填补这些空缺。BiGR不仅能够生成图像,还能在......
  • 二分图
    二分图速通定义若一个无向图\(G=(V,E)\)的点集\(V\)可以分解成两个互不相交的子集\(A,B\),且对于所有边\((i,j)\)的端点\(i,j\)都分别属于子集\(A,B\)中的元素,则称\(G\)是一个二分图。判定一张无向图是二分图,当且仅当图中不存在奇环。故我们有染色算法判定二分图......
  • 二分图
    二分图概念假设\(G=(V,E)\)是一个无向图,若点集\(V\)可以分解成互不相交的子集\((A,B)\),并且图中所有边\((i,j)\)的端点\(i\)、\(j\)分别属于子集\(A\)、\(B\),则称\(G\)是一个二分图定理:一张无向图时二分图,当且仅当图中不存在奇环。染色法判定一个图是否是二分图......
  • 二分图学习笔记
    1.概念假设图\(G=(V,E)\)是无向图,若顶点集\(V\)可以分成两个互不相交的子集\((A,B)\),且任意边\((i,j)\)两端点分别属于两子集,则图\(G\)是二分图判断方法:染色法匹配:无公共点的边集匹配数:边集中边的个数最大匹配:匹配数最大的匹配增广路:设M是一个匹配,如果存在一条连接两个未匹......
  • 【论文复现】输电线路故障判别与测距研究(Matlab代码、Simulink仿真实现)
       ......
  • 【论文复现】输电线路故障判别与测距研究(Matlab代码、Simulink仿真实现)
       ......
  • 【论文复现】输电线路故障判别与测距研究(Matlab代码、Simulink仿真实现)
       ......
  • VBA中的基础知识:类型判别及定义
    变量类型 用TypeName()函数可以判断变量类型。TypeName(i)="Single"就是单精度浮点数TypeName(i)="String"就是字符串 另外IsNumeric判断变量的值是否为数值isdate判断变量的值是否为日期isnull判断变量的值是否包含任何有效数据isempty判断变量的值是否为空......