二分图学习

图论中的难见就是建图然后套用算法。

特点:

仅仅能一一相应,即XX仅仅能有一个人。

先来一个比較好的入门资料二分图最大匹配 參考 二分图建图方法

算法的思路是不停的找增广路径, 并添加匹配的个数,增广路径顾名思义是指一条能够使匹配数变多的路径,在匹配问题中,增广路径的表现形式是一条”交错路径”,也就是说这条由图的边组成的路径。 它的第一条边是眼下还没有參与匹配的,第二条边參与了匹配。第三条边没有..最后一条边没有參与匹配,而且始点和终点还没有被选择过。这样交错进行,显然他有奇数条边。

那么对于这样一条路径,我们能够将第一条边改为已匹配。第二条边改为未匹配…以此类推。

也就是将全部的边进行”反色”,easy发现这样改动以后,匹配仍然是合法的,但是匹配数添加了一对。另外。单独的一条连接两个未匹配点的边显然也是交错路径。能够证明。当不能再找到增广路径时,就得到了一个最大匹配,这也就是匈牙利算法的思路。


3个重要结论:

最小点覆盖数: 最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和当中一个点关联。

能够证明:最少的点(即覆盖数)=最大匹配数

最小路径覆盖=最小路径覆盖=|N|-最大匹配数

用尽量少的不相交简单路径覆盖有向无环图G的全部结点。解决此类问题能够建立一个二分图模型。把全部顶点i拆成两个:X结点集中的i和Y结点集中的i’。假设有边i->j,则在二分图中引入边i->j’,设二分图最大匹配为m,则结果就是n-m。

二分图最大独立集=顶点数-二分图最大匹配

在N个点的图G中选出m个点,使这m个点两两之间没有边。求m最大值。

假设图G满足二分图条件,则能够用二分图匹配来做.最大独立集点数 = N - 最大匹配数。

做题见过的几种建图方案:

1. 二维矩阵中,1X2的方格覆盖将图看成国际象棋那种黑白相间

2. 2015上海邀请赛热身题B看成一直黑白相间下去的二分图

3. 有向无环图,每条边相连的两点看成二分图的两部分

4. 二维矩阵中。每行每列 仅仅能放一个。将X坐标集合看成一部分。Y看成一部分。

交点有ship的时候相应的行和列才不能够放,就是说你选了相应的行,相当于相应的列也被选择。然后这不就是一种匹配吗,所以我们就能够依据这种性质来建立二部图。从而转化成求二部图最大匹配的问题。

将横着的没有被阻挡的块合并成一个大块。将竖着的没有被阻挡的块合并成一个大块。

这样得到若干个横向块。和纵向块。假设一横向块与纵向块之间有共同的点。那么就将这两个大块连线(构造一个横向块与纵向块的邻接矩阵)。

构造好之后就能够算横向块与纵向块的最大匹配数。

(HDU 5093 ZOJ 1654 ZOJ 3156)

5. 最小路径覆盖问题,原始的最小路径覆盖的各个路径是不能有同样的点的,假设是但是可相交的路径覆盖就要先求一次闭包。poj 2594 參考



模板

#include <stdio.h>
#include <string.h>
#define MX 155
int n, m;
bool g[MX][MX], v[MX];
int match[MX];

bool find(int x) {
    for(int i = 1; i <= n; ++i) {
        if(!v[i] && g[x][i]) {
            v[i] = 1;
            if(match[i] == -1 || find(match[i])) {
                match[i] = x;
                return 1;
            }
        }
    }
    return 0;
}

void hungary() {
    int ans = 0;
    for(int i = 1; i <= n; ++i) {
        memset(v, 0, sizeof(v));
        if(find(i)) ans ++;
    }
    printf("%d\n", n - ans);
}
int main() {
    int cas;
    scanf("%d", &cas);
    while(cas --) {
        while (scanf("%d%d", &n, &m) != EOF) {
            memset(g, 0, sizeof(g));
            memset(match, -1, sizeof(match));
            int a, b;
            for(int i = 1; i <= m; ++i) {
                scanf("%d%d", &a, &b);
                g[a][b] = 1;
            }
            hungary();
        }
    }
    return 0;
}
时间: 2024-11-09 10:08:37

二分图学习的相关文章

二分图学习整理

今天学习了一下二分图,赶紧总结整理一下: 二分图问题,有很多,但归根结底还是求最大匹配数. 二分图最大匹配及常用建图方法 Point 1: 二分图中的最小点覆盖数 = 最大匹配数 最小点覆盖:也就是说用最少的点覆盖所有的边 Point 2 : 二分图中的最小路径覆盖 = 顶点数 - 最大匹配数 最小路径覆盖:也叫最小边覆盖,是指用尽量少的不相交的路径覆盖图中的所有顶点. Point 3: 二分图的最大独立集合 = 顶点数 - 最大匹配数 独立集合:即 独立于所有联通边集之外的点,也就是与图中任意

【巨坑】 二分图学习笔记 [2017年6月计划 学习二分图]

1.二分图:    ①把一个图的点集划为两个不相交的集合U,V,使得每一条边都连接U,V中的节点. ②(等价定义,更方便看)不含边数为奇数的环的图 2.匹配(matching): 边集,每一条边所连顶点互不相同 3.最大匹配: 所含边数最大的匹配 4.完美匹配: 所有顶点都被匹配,完美匹配一定是最大匹配. 5.交替路: 从一个非匹配点出发,依次走非匹配边,匹配边,非匹配边....交替走,形成交替路 6.增广路: 从一个非匹配点出发,走交替路,经过另一个非匹配点,则这条路径叫做增广路   增广路特

二分图学习小结

二分图的性质:在无向图G中,至少要有两个点.如果存在回路,那么回路必为偶数边的回路.. 匹配: 在图论中,一个匹配是一个边的集合,其中任意两条边都没有公共顶点. 最大匹配: 一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配 最大匹配数:最大匹配的匹配边的数目 完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配. 最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择 最大独立数:选取最多的点,使任意所选两点均不相连 最小路径覆盖数:对于一个 DAG

二分图的学习:基础思路(杨)(剪辑版)

剪辑其他网友朋友的博文,谢谢他了! 匈牙利算法是解决寻找二分图最大匹配的. (一)预备知识     什么是二分图:二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同 的顶点集(i in A,j in B),则称图G为一个二分图. 什么是匹配:把上图想象成3男4女搞对象(无同性恋),连线代表彼此有好感,但最终只能1夫1妻,最终的配对结果连线就是一个匹配.匹配可

二分图匹配学习记录

导读:重新系统的学习了二分图匹配,感觉面对图论题又有了底气. (资料来源:http://wenku.baidu.com/link?url=AdT8Ftpj14qoiwS4Ey-DzJCiNVu6VTzWOxsWjcXuNBuCboGXMf67w8QNedjL2ECWCbQDZpu7-uwopB2KGreoNk65hOsEgNj7uyRmeHaP0f7) 几个概念: 1.最大独立集:一个二分图中最大的一个点集,该点集中每个点互不相连. 2.最小顶点覆盖:在二分图中,用最少的点,让所有边都与至少一个

二分图匹配-匈牙利算法【学习】

首先二分图匹配的基础概念得清楚:二分图: 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图.匹配: 两两不含公共端点的边集合M称为匹配(简单的说就是右边的点只能连一条边)极大匹配: 指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数最大匹配: 所有极大匹配当中边数最大的一个匹配增广路: 若P是图G中一条连通两个未匹配顶

km算法(二分图最大权匹配)学习

啦啦啦! KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转 化为求完备匹配的问题的.设顶点Xi的顶标为A[i],顶点Yi的顶标为B[i],顶点Xi与Yj之间的边权为w[i,j].在算法执行过程中的任一时刻,对于任一条边(i,j), A[i]+B[j]>=w[i,j]始终成立. KM算法的正确性基于以下定理: *  若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配. * 这个定理是显然

hihoCoder 1393 网络流三&#183;二分图多重匹配 (网络流学习#3 记录)

题目链接:http://hihocoder.com/problemset/problem/1393 话说我之前一直不知道二分匹配可以用网络流做... #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=205; struct ss{ int v,c,nxt; } e[N*20]; int head[N],tot,vis[N],n,m,a[N],b[N],s

算法学习三阶段

?? 第一阶段:练经典经常使用算法,以下的每一个算法给我打上十到二十遍,同一时候自己精简代码, 由于太经常使用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都能够把程序打 出来. 1.最短路(Floyd.Dijstra,BellmanFord) 2.最小生成树(先写个prim,kruscal 要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘.判线段相交.然后写个凸包. 6.BFS.DFS,同一时候熟练hash 表(要熟,要灵活,代码要