二分图相关问题

update:2019/09/25 重新将两篇二分图的学习报告整合



一,二分图的定义

对于一个图上的所有节点能够分成两个集合且保证边仅存在在两个集合之间,集合内部没有边,这样的图叫做二分图。

二,二分图的一些性质(一些比较重要的性质)

1,二分图没有奇环

2,二分图的最小顶点覆盖

定义:若选择一个点即覆盖了所有与这个点相连的边,最小点覆盖就是选择最少的点覆盖所有的边。

定理:二分图的最小顶点覆盖数=二分图的最大匹配数

3,二分图的最大独立集

定义:选取一些点使得任何两个点之间没有边相连,能选取的最多的顶点称为最大独立集

定理:二分图的最大独立集=二分图的顶点数-二分图的最小顶点覆盖数

三,二分图的判断方法—染色法

算法流程:即对于每条边(u,v)如果v没有染色就染上与u相反的颜色,如果u和v颜色相同,则证明不是二分图,

若能完成所有的染色则证明是一个二分图。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5
 6 using namespace std;
 7
 8 struct node
 9 {
10     int ed,nxt;
11 };
12 node edge[2333];
13 int n,m,first[2333],cnt;
14 int color[2333];
15 bool flag;
16
17 inline void add_edge(int s,int e)
18 {
19     cnt++;
20     edge[cnt].ed=e;
21     edge[cnt].nxt=first[s];
22     first[s]=cnt;
23     return;
24 }
25
26 inline void pd(int pos,int c)
27 {
28     color[pos]=c;
29     for(int i=first[pos];i;i=edge[i].nxt)
30     {
31         int e=edge[i].ed;
32         if(color[pos]==color[e]) {flag=false;return;}
33         else if(color[e]==0) pd(e,-c);
34     }
35 }
36
37 int main()
38 {
39     scanf("%d%d",&n,&m);
40     for(int i=1;i<=m;i++)
41     {
42         int s,e;
43         scanf("%d%d",&s,&e);
44         add_edge(s,e);
45         add_edge(e,s);
46     }
47     flag=true;
48     memset(color,0,sizeof(color));
49     for(int i=1;i<=n;i++)
50     {
51         if(!color[i]) pd(i,1);
52         if(!flag)
53         {
54             printf("NO");
55             return 0;
56         }
57     }
58     printf("YES");
59     return 0;
60 }

四,二分图的匹配问题

匹配:一个左端点+一条边+一个右端点 (且左端点和右端点只能在一个匹配里) 称为一个匹配

1,完美匹配

即二分图的左右所有端点都被匹配了。

2,最大匹配—匈牙利算法

算法过程:寻找增广路径

算法流程:

从左侧集合中的第一个点开始寻找匹配

如果某条边的中点没有被匹配过就匹配上,否则就寻找是否存在增广路径。

寻找增广路径的过程其实是一个再匹配的过程,让已经配对的左集合端点暂时取消匹配而去找下一个能匹配的右集合端点

如果能找到就存在增广路径,否则不存在。

1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define maxn 2005
 6
 7 using namespace std;
 8
 9 struct node
10 {
11     int ed,nxt;
12 };
13 node edge[maxn*maxn];
14 int n,m,e,first[maxn],ans,cnt;
15 bool used[maxn];
16 int match[maxn];
17
18 inline void add_edge(int st,int ed)
19 {
20     cnt++;
21     edge[cnt].ed=ed;
22     edge[cnt].nxt=first[st];
23     first[st]=cnt;
24     return;
25 }
26
27 inline bool dfs(int k)
28 {
29     for(int i=first[k];i!=0;i=edge[i].nxt)
30     {
31         int e=edge[i].ed;
32         if(!used[e])
33         {
34             used[e]=true;
35             if(!match[e]||dfs(match[e]))
36             {
37                 match[e]=k;
38                 return true;
39             }
40         }
41     }
42     return false;
43 }
44
45 int main()
46 {
47     scanf("%d%d%d",&n,&m,&e);
48     for(int i=1;i<=e;i++)
49     {
50         int st,ed;
51         scanf("%d%d",&st,&ed);
52         if(st<=n&&ed<=m) add_edge(st,ed);
53     }
54     for(int i=1;i<=n;i++)
55     {
56         memset(used,false,sizeof(used));
57         if(dfs(i)) ans++;
58     }
59     printf("%d",ans);
60     return 0;
61 }

原文地址:https://www.cnblogs.com/Hoyoak/p/11583799.html

时间: 2024-10-12 20:47:41

二分图相关问题的相关文章

二分图相关题

HDU 1281 由于每行最多放一个,每列最多放一个(不能放置的位置不影响攻击,就是由于没注意这句话,把这题当做行列覆盖模型做了好久0.0) 所以把行列直接当做二分图X和Y集.能够放置的点的行列连边,求出的完备匹配就是第二个答案. 至于第一个答案求关键点,就枚举删除一条边是否能任然得到完备匹配,若不行,则是关键点. 我的代码c++会WA,不知道为什么.求教啊. #include<cstdio> #include<cstring> #include<algorithm>

二分图相关知识(来自kuangbin博客)

二分图匹配(匈牙利算法) 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 K?nig定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边. 2.最小路径覆盖=最小路径覆盖=|G|-最大匹配数 在一个N*N的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点, 且任何一个顶点有且只有一条路径与之关联:(如

【自用】二分图相关总结

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/45092617"); } 概念: 最大匹配:二分图上最大对数的点对使得对之间有连边,且任意两点对4个点之间互不相同 最大匹配:无视上面那条,其实就是你找一个点,然后给它连一个有边连过去且没匹配过的点,然后就称得到一个匹配.最大匹配就是

《啊哈算法》——割点、割边、二分图

这篇文章我们简单的介绍求解图的割点.割边和二分图相关的概念. 割点: 对于含n个点.m条边的连通无向图G,如果去掉顶点vi(并同时去掉与之相连的边),使得G不再连通,那么称vi是一个割点. 通过其定义,我们不难判断某个点是否是割点,但是现在我们面临的问题是,如何给出一个图G,编码让计算机求解割点呢? 首先我们考虑这样一个问题,判定某个点的指标是什么.我们通过人脑来判断其是否是割点,其实是利用非常模糊的视觉效应,即“通过去掉该点观察图是否连通”即可,而如果想要通过计算机来判断,就需要非常量化的判断

&quot;《算法导论》之‘图’&quot;:不带权二分图最大匹配(匈牙利算法)

博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利算法 1. 前言 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图.准确地说:把一个图的顶点划分为两个不相交集 U 和V ,使得每一条边都分别连接U.V中的顶点.如果存在这样的划分,则此图为一个二分图.二分图的一个等价定义是:不含有「含奇数条边的环」的图.

二分图类题目集合

此文用来总结二分图相关知识的题目,以后遇到了就囤在一起总结吧. 最近遇到的一道最小路径覆盖的题目,其实很裸,忘了也没看出来就是最小路径覆盖. 第四届“恒生杯”程序设计大赛决赛 A http://acm.hust.edu.cn/problem/show/1643 题意:有n个物品,每一天只能选取一些满足条件的物品,即选取的物品相邻之间要满足abs(a[i]-a[j]) >= k,问最少多少天能够选完所有物品. 分析:首先建立一个图,对于abs(a[i]-a[j])>=k的i,j(i < j

最小路径覆盖和最小边覆盖及相关性质

[最小路径覆盖] 首先给出公式:DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数. 一个PXP的有向图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联:(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次):如果不考虑图中存在回路,那么每条路径就是一个弱连通子集. 由上面可以得出: 1.一个单独的顶点是一条路径: 2.如果存在一路径p1,p2,......pk,其中p1 为起点,pk

[转]最小路径覆盖和最小边覆盖及相关性质

转载自:http://www.cnblogs.com/icode-girl/p/5418461.html [最小路径覆盖] 首先给出公式:DAG的最小路径覆盖数=DAG图中的节点数-相应二分图中的最大匹配数. 一个PXP的有向图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联:(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次):如果不考虑图中存在回路,那么每条路径就是一个弱连通子集. 由上面可以得出

二分图详解及总结

二分图: 二分图中,顶点可以分为两个集合,每一条边的端点都分别位于这两个集合. 二分图的判定: 可以利用Bfs或者Dfs进行黑白染色,共享一条边的两点异色,检查一下是否存在矛盾即可. 相关题目:Hdu 2444 The Accomodation of Students        Hdu 5313 Bipartite Graph bfs代码: 1 void bfs (int s) 2 { 3 int p, q, zreo, one, num; 4 queue <int> Q; 5 zreo