首页 > 其他分享 >二分图

二分图

时间:2023-08-01 22:13:12浏览次数:21  
标签:二分 匹配 int blog color https

1.是什么

一种特殊的图,这种图可以把图中的点分成两个集合,所有的边都在这两个集合之间,也就是说集合内部的点之间是没有边的。

2.怎么判断

一般来说用染色法判断,从任意一个结点开始交替染色,若与某节点连边的结点已被染色,且颜色与该节点相同,则该图不是二分图。

代码:

int paint(int x,int idx){
    color[x]=idx;
    for(int i=head[x];i;i=nxt[i]){
        if(!color[ve[i]]){
            if(!paint(ve[i],3-idx)) return 0;
        }
        else if(color[x]==color[ve[i]]) return 0;
    }
    return 1;
}

3.二分图的匹配

如图1这样一个二分图

图2即为它的极大匹配

图三即为它的最大匹配,同时也是完全匹配

 来自博客:https://blog.csdn.net/weixin_46522531/article/details/128469751 写的真的很好

最后一句话可改为 完全匹配一定是最大匹配,但最大匹配不一定是完全匹配

4.如何求最大匹配

 增广路:连接两个未匹配顶点,且该路径的组成成分(?)为未匹配、匹配交替,且最后由未匹配结束

如果我们在二分图其中一个点的集合里一直找增广路直到找不到为止,此时就可以得到最大匹配了,匈牙利算法

果然这里还是讲不清楚 请移步这篇博客:https://zhuanlan.zhihu.com/p/402091571 看看动图,多读几遍就懂了

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const long long N=1e6+10;
int n,m,e,u,v,ver[N],cnt=0;
int book[550][550],h[N];
int dfs(int x){
    for(int i=1;i<=m;i++){
        if(book[x][i]==1&&ver[i]==0){
            ver[i]=1;
            if(h[i]==0||dfs(h[i])){
                h[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    scanf("%d%d%d",&n,&m,&e);
    for(int i=1;i<=e;i++){
        scanf("%d%d",&u,&v);
        book[u][v]=1;
    }
    for(int i=1;i<=n;i++){
        memset(ver,0,sizeof(ver));
        cnt+=dfs(i);
    }
    printf("%d\n",cnt);
    return 0;
}

如果还是不太明白移步下面几篇博客:

https://zhuanlan.zhihu.com/p/353364452

https://blog.csdn.net/weixin_46522531/article/details/128469751

https://zhuanlan.zhihu.com/p/402091571

https://blog.csdn.net/dark_scope/article/details/8880547

标签:二分,匹配,int,blog,color,https
From: https://www.cnblogs.com/dgdger/p/17599223.html

相关文章

  • 二分查找
    二分查找前提:有序思路:mid=(left+right)/2若mid=value,输出mid下标若mid<value,mid=left+1若mid>value,mid=right-1publicclassTest2{@Testpublicvoidtest1(){int[]arr={-99,-54,-2,0,0,2,33,43,256,999};......
  • 二分图的最小顶点覆盖 最大独立集 最大团
    二分图的最小顶点覆盖最大独立集最大团重要结论写在最前面:①最小顶点覆盖等于二分图的最大匹配②最大独立集=所有顶点数-最小顶点覆盖③二分图的最大团=补图的最大独立集一、二分图的最小顶点覆盖定义:假如选了一个点就相当于覆盖了以它为端点的所有边。最小顶点覆......
  • 二分查找常见变种方法的代码实现
    二分查找变种:1.查找大于target的所有值的最小索引;2.查找等于target的所有值的最大索引(上界);3.查找大于target的所有值的最大索引; 代码示例:/***二分查找工具对象*/constBinarySearch=(function(){return{/***找出大于target的所有值......
  • 二分
    二分答案例题abc312C-InvisibleHandqiansui_code......
  • 二分查找法
    文章目录二分查找法二分查找的关键:二分查找法演示二分查找法适用于有序数组,顺序查找绝大多数情况有效但是由于它是一个一个元素进行查找,其效率很低,只有一个for循环二分查找的关键:找到最左边元素(left)和最右边元素(right),确定中间元素(mid)intr=0; scanf("%d",&r); intarr[]={0......
  • abc312c <二分答案>
    题目C-InvisibleHand思路二分X,同时二分得到buyer和seller的人数(很精巧的二分~);当然,从复杂度角度,\(O(N\logN)\)也是可以的;实际上可以写成\(O(N)\)的形式?感觉线性扫描也可?代码点击查看代码#include<iostream>#include<algorithm>#include<vector>#include<cst......
  • 最长单调上升子序列(贪心+二分)
    这个的思路就是再开一个数组,存储长度为i的最长上升子序列的最后一个数字是多少,这个数组可以保证递增,之后开始二分,只要当前这个数是大于i-1的数但小于i的数,那就可以更新i的数,这里就是贪心的思想,相同长度结尾数字越小越好intlen=0;for(inti=1;i<=n;i++){intl=1,r=......
  • 【C语言】二分查找算法
    在⼀个升序的数组中查找制定的数字n,很容易想到的⽅法就是遍历数组,但是这种⽅法效率⽐较低,⽐如我买了⼀双鞋,你好奇问我多少钱,我说不超过300元。你还是好奇,你想知道到底多少,我就让你猜,你会怎么猜?你会1,2,3,4...这样猜吗?显然很慢;⼀般你都会猜中间数字,⽐如:150,然后看⼤了还是⼩了,这就是......
  • 代码随想录算法训练营第一天| LeetCode 704. 二分查找、LeetCode 27. 移除元素
    704.二分查找    题目链接:https://leetcode.cn/problems/binary-search/   视频链接:https://www.bilibili.com/video/BV1fA4y1o715     文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html    卡哥的题目建......
  • 快排/归并/二分
    排序快速排序主要思想:分治排序方式:确定分界点:左边界:q[l],中间值:q[(l+r)/2],右边界,或者随机调整区间:小于等于x的在x左半边,大于等于x的在x右半边(最难的部分)法一:开a[],b[]扫描一遍q[],q[i]>=xq[i]->a[];q[i]<=xq[i]->b[];a[]->q[]b[]->b[]法二(更优美):......