二分图及二分图匹配

合集下载

图论:二分图多重匹配

图论:二分图多重匹配

图论:⼆分图多重匹配使⽤最⼤流和费⽤流解决⼆分图的多重匹配之前编辑的忘存了好⽓啊。

本来打算学完⼆分图的乱七⼋糟的匹配之后再去接触⽹络流的,提前撞到了之前我们说的⼆分图最⼤匹配和⼆分图最⼤权匹配有⼀个特点,那就是没个点只能与⼀条边相匹配如果规定⼀个点要与L条边相匹配,这样的问题就是⼆分图的多重匹配问题然后根据边是否带权重,⼜可以分为⼆分图最⼤多重匹配和⼆分图最⼤权多重匹配(⼆分图多重最佳完美匹配)⾸先给出⼆分图多重最⼤匹配的做法:在原图上建⽴源点S和汇点T,S向每个X⽅点连⼀条容量为该X⽅点L值的边,每个Y⽅点向T连⼀条容量为该Y⽅点L值的边原来⼆分图中各边在新的⽹络中仍存在,容量为1(若该边可以使⽤多次则容量⼤于1),求该⽹络的最⼤流,就是该⼆分图多重最⼤匹配的值然后给出⼆分图多重最优匹配(⼆分图多重最⼤权匹配)的做法:在原图上建⽴源点S和汇点T,S向每个X⽅点连⼀条容量为该X⽅点L值、费⽤为0的边,每个Y⽅点向T连⼀条容量为该Y⽅点L值、费⽤为0的边原来⼆分图中各边在新的⽹络中仍存在,容量为1(若该边可以使⽤多次则容量⼤于1),费⽤为该边的权值。

求该⽹络的最⼤费⽤最⼤流,就是该⼆分图多重最优匹配的值这道题⾥⾯,⼀共有X⽅点这么多的电影,每个电影需要拍摄多少天就是对应的X⽅点L值,然后每⼀天是⼀个Y⽅点,由于每⼀天只能拍摄⼀部电影,所有Y⽅点的L值均为1下⾯介绍⼀下实现:int n,sum,cnt,ans;int g[maxn],cur[maxn];int str[25][10];struct Edge{int u,v,next,cap,flow;}e[maxm];这⾥⾯的cur数组是g数组的临时数组str⽤来保存每⼀个电影可以在哪⼀天拍摄Edge是⽹络流图⾥⾯的边void addedge(int u,int v,int c){e[++cnt].u=u;e[cnt].v=v;e[cnt].cap=c;e[cnt].flow=0;e[cnt].next=g[u];g[u]=cnt;e[++cnt].u=v;e[cnt].v=u;e[cnt].cap=0;e[cnt].flow=0;e[cnt].next=g[v];g[v]=cnt;}建图的时候,注意怎么赋值的接下来根据题意建图:for(int i=1;i<=n;i++){for(int j=1;j<=7;j++)scanf("%d",&str[i][j]);scanf("%d%d",&d,&w);sum+=d;addedge(0,i,d); //容量为需要多少天for(int j=1;j<=7;j++)for(int k=0;k<w;k++)if(str[i][j]) addedge(i,20+k*7+j,1);}for(int i=21;i<=370;i++) addedge(i,371,1);ans=maxflow(0,371);0为源点,371为汇点sum最后进⾏⼀个统计,和源点出发的最⼤流量进⾏⽐较,如果相等,说明电影排的开然后是求最⼤流的⼀个板⼦int maxflow(int st,int ed){int flowsum=0;while(bfs(st,ed)){memcpy(cur,g,sizeof(g));flowsum+=dfs(st,ed,INF);//cout<<"#"<<flowsum<<" ";}return flowsum;}具体的DFS和BFS这⾥不作为重点,以后再说下⾯给出完整的实现:1 #include<cstdio>2 #include<cstring>3 #include<algorithm>4using namespace std;5const int INF=1000000000;6const int maxn=1005;7const int maxm=20005;8int n,sum,cnt,ans;9int g[maxn],cur[maxn];10int str[25][10];11struct Edge{int u,v,next,cap,flow;}e[maxm];12void addedge(int u,int v,int c)13 {14 e[++cnt].u=u;e[cnt].v=v;e[cnt].cap=c;15 e[cnt].flow=0;e[cnt].next=g[u];g[u]=cnt;1617 e[++cnt].u=v;e[cnt].v=u;e[cnt].cap=0;18 e[cnt].flow=0;e[cnt].next=g[v];g[v]=cnt;19 }20int q[maxn],vis[maxn],d[maxn];21bool bfs(int st,int ed)22 {23 memset(q,0,sizeof(q));24 memset(vis,0,sizeof(vis));25 memset(d,-1,sizeof(d));26 vis[st]=1;d[st]=0;27int h=0,t=1;28 q[t]=st;29while(h!=t)30 {31 h=h%maxn+1;32int u=q[h];33for(int tmp=g[u];tmp;tmp=e[tmp].next)34 {35if(!vis[e[tmp].v]&&e[tmp].cap>e[tmp].flow)36 {37 vis[e[tmp].v]=1;38 d[e[tmp].v]=d[u]+1;39if(e[tmp].v==ed) return true;40 t=t%maxn+1;41 q[t]=e[tmp].v;42 }43 }44 }45return false;46 }47int getpair(int x)48 {49if(x%2==0)50return x-1;51else return x+1;52 }53int dfs(int x,int ed,int a)54 {55if(x==ed||a==0) return a;56int flow=0,f;57for(int tmp=cur[x];tmp;tmp=e[tmp].next)58 {59if(d[e[tmp].v]==d[x]+1&&(f=dfs(e[tmp].v,ed,min(a,e[tmp].cap-e[tmp].flow)))>0)60 {61 e[tmp].flow+=f;62 e[getpair(tmp)].flow-=f;63 a-=f;64 flow+=f;65if(a==0) break;66 }67 }68return flow;69 }70int maxflow(int st,int ed)71 {72int flowsum=0;73while(bfs(st,ed))74 {75 memcpy(cur,g,sizeof(g));76 flowsum+=dfs(st,ed,INF);77//cout<<"#"<<flowsum<<" ";78 }79return flowsum;8081 }82void init()83 {84 sum=cnt=0;85 memset(g,0,sizeof(g));86 }87int main()88 {89int T,d,w;90 scanf("%d",&T);91while(T--)92 {93 init();94 scanf("%d",&n);95for(int i=1;i<=n;i++)96 {97for(int j=1;j<=7;j++)98 scanf("%d",&str[i][j]);99 scanf("%d%d",&d,&w);100 sum+=d;101 addedge(0,i,d); //容量为需要多少天102for(int j=1;j<=7;j++)103for(int k=0;k<w;k++)104if(str[i][j]) addedge(i,20+k*7+j,1);105 }106for(int i=21;i<=370;i++) addedge(i,371,1);107 ans=maxflow(0,371);108if(ans==sum) printf("Yes\n");109else printf("No\n");110 }111return0;112 }据说这是典型的最⼤流题⽬,然⽽为了强⾏安利⼀波⼆分图的多重匹配,就不说成那个了。

二分图匹配(匈牙利算法)

二分图匹配(匈牙利算法)

设G=(V,{R})是一个无向图。

如顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属两个不同的子集。

则称图G为二分图。

v给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

v选择这样的边数最大的子集称为图的最大匹配问题(maximal matching problem)v如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。

最大匹配在实际中有广泛的用处,求最大匹配的一种显而易见的算法是:先找出全部匹配,然后保留匹配数最多的。

但是这个算法的复杂度为边数的指数级函数。

因此,需要寻求一种更加高效的算法。

匈牙利算法是求解最大匹配的有效算法,该算法用到了增广路的定义(也称增广轨或交错轨):若P是图G中一条连通两个未匹配顶点的路径,并且属M的边和不属M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M 的一条增广路径。

由增广路径的定义可以推出下述三个结论:v 1. P的路径长度必定为奇数,第一条边和最后一条边都不属于M。

v 2. P经过取反操作(即非M中的边变为M中的边,原来M中的边去掉)可以得到一个更大的匹配M’。

v 3. M为G的最大匹配当且仅当不存在相对于M的增广路径。

从而可以得到求解最大匹配的匈牙利算法:v(1)置M为空v(2)找出一条增广路径P,通过取反操作获得更大的匹配M’代替Mv(3)重复(2)操作直到找不出增广路径为止根据该算法,我选用dfs (深度优先搜索)实现。

程序清单如下:int match[i] //存储集合m中的节点i在集合n中的匹配节点,初值为-1。

int n,m,match[100]; //二分图的两个集合分别含有n和m个元素。

bool visit[100],map[100][100]; //map存储邻接矩阵。

bool dfs(int k){int t;for(int i = 0; i < m; i++)if(map[k][i] && !visit[i]){visit[i] = true;t = match[i];match[i] = k; //路径取反操作。

二分图理论

二分图理论

*7.5 二部图及匹配7.5.1二部图在许多实际问题中常用到二部图,本节先介绍二部图的基本概念和主要结论,然后介绍它的一个重要应用—匹配。

定义7.5.1 若无向图,G V E =的顶点集V 能分成两个子集1V 和2V ,满足(1)12V V V =,12V V φ=;(2)(,)e u v E ∀=∈,均有1u V ∈,2v V ∈。

则称G 为二部图或偶图(Bipartite Graph 或Bigraph),1V 和2V 称为互补顶点子集,常记为12,,G V V E =。

如果1V 中每个顶点都与2V 中所有顶点邻接,则称G 为完全二部图或完全偶图(Complete Bipartite Graph),并记为,r s K ,其中12,r V s V ==。

由定义可知,二部图是无自回路的图。

图7-55中,(),(),(),(),()a b c d e 都是二部图,其中(),(),(),()b c d e 是完全二部图1,32,32,43,3,,,K K K K 。

图7-55二部图示例显然,在完全二部图中,r s K 中,顶点数n r s =+,边数m rs =。

一个无向图如果能画成上面的样式,很容易判定它是二部图。

有些图虽然表面上不是上面的样式,但经过改画就能成为上面的样式,仍可判定它是一个二部图,如图7-56中()a 可改画成图()b ,图()c 可改画成图()d 。

可以看出,它们仍是二部图。

图7-56二部图示例定理7.5.1 无向图,G E =为二部图的充分必要条件为G 中所有回路的长度均为偶数。

证明 先证必要性。

设G 是具有互补节点子集1V 和2V 的二部图。

121(,,,,)k v v v v 是G 中任一长度为k 的回路,不妨设11v V ∈,则211m v V +∈,22m v V ∈,所以k 必为偶数,不然,不存在边1(,)k v v 。

再证充分性。

设G 是连通图,否则对G 的每个连通分支进行证明。

算法学习:图论之二分图的最优匹配(KM算法)

算法学习:图论之二分图的最优匹配(KM算法)

二分图的最优匹配(KM算法)KM算法用来解决最大权匹配问题:在一个二分图内,左顶点为X,右顶点为Y,现对于每组左右连接XiYj有权wij,求一种匹配使得所有wij的和最大。

基本原理该算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。

设顶点Xi的顶标为A[ i ],顶点Yj的顶标为B[ j ],顶点Xi与Yj之间的边权为w[i,j]。

在算法执行过程中的任一时刻,对于任一条边(i,j),A[ i ]+B[j]>=w[i,j]始终成立。

KM算法的正确性基于以下定理:若由二分图中所有满足A[ i ]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。

首先解释下什么是完备匹配,所谓的完备匹配就是在二部图中,X点集中的所有点都有对应的匹配或者是Y点集中所有的点都有对应的匹配,则称该匹配为完备匹配。

这个定理是显然的。

因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和。

所以相等子图的完备匹配一定是二分图的最大权匹配。

初始时为了使A[ i ]+B[j]>=w[i,j]恒成立,令A[ i ]为所有与顶点Xi关联的边的最大权,B[j]=0。

如果当前的相等子图没有完备匹配,就按下面的方法修改顶标以使扩大相等子图,直到相等子图具有完备匹配为止。

我们求当前相等子图的完备匹配失败了,是因为对于某个X顶点,我们找不到一条从它出发的交错路。

这时我们获得了一棵交错树,它的叶子结点全部是X顶点。

现在我们把交错树中X顶点的顶标全都减小某个值d,Y顶点的顶标全都增加同一个值d,那么我们会发现:1)两端都在交错树中的边(i,j),A[ i ]+B[j]的值没有变化。

也就是说,它原来属于相等子图,现在仍属于相等子图。

2)两端都不在交错树中的边(i,j),A[ i ]和B[j]都没有变化。

二分图相关问题

二分图相关问题

X X S X X
X X X X
X代表攻击范围,S代表骑 士
分析
对棋盘染色,设方格的坐标为(x,y),x和y同奇 偶的方格对应X集合,不同奇偶的对应Y集合。 由于骑士沿着“日”字形路线攻击,所以每个 攻击肯定是处于X集合和Y集合之间,而不可 能在两个集合内部。 显然,转化后变为求二分图的最大独立集
匈牙利算法
简要说明:find函数用于判断从k点开始是否能 够找到一条交错路。对于每个可以与k匹配的 顶点j,假如它未被匹配,交错路就已经找到; 假如j已与某顶点x匹配,那么只需调用find(x) 来求证x是否可以与其它顶点匹配,如果返回 true的话,仍可以使j与k匹配;这就是一次 DFS。每次DFS时,要标记访问到的顶点 (cover[j]=true),以防死循环和重复计算。
例题分析
Hanoi Tower Troubles Again! (OIBH Contest)
ZOJ 1239 题目大意:给定柱子数N,按编号从小到大放球, 要求:如果该球不在最底数,则该球和它下面一个 球的编号之和必须为完全平方数。 问对于给定的N,最多能放多少球上去。 N<=50
例题分析
分析
铺放方法
1.2. .333 444. ..2.
Sample Output 4
分析
最小覆盖是覆盖所有的边,因此泥地对应边 建图方式类似于皇家卫士,也是利用行连通块 和列连通块做点,单位泥地对应二分图中的边 要求放最少的板覆盖全部的泥地,转化为求最 小覆盖
二分图最大独立集
图的独立集:寻找一个点集,其中任意两点在 图中无对应边 一般图的最大独立集是NP完全问题 二分图的最大独立集=图的点数-最大匹配数
二分图最小覆盖
图的覆盖:寻找一个点集,使得图中每一条边 至少有一点在该点集中

二分图匹配

二分图匹配

二分图匹配一、二分图的概念二分图又称作二部图,是图论中的一种特殊模型。

设G=(V,{R})是一个无向图。

如顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属两个不同的子集。

则称图G为二分图。

二、最大匹配给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

选择这样的边数最大的子集称为图的最大匹配问题(maximal matching problem)如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。

三、匈牙利算法求最大匹配的一种显而易见的算法是:先找出全部匹配,然后保留匹配数最多的。

但是这个算法的复杂度为边数的指数级函数。

因此,需要寻求一种更加高效的算法。

1、增广路的定义(也称增广轨或交错轨):若P是图G中一条连通两个未匹配顶点的路径,并且属M的边和不属M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。

由增广路的定义可以推出下述三个结论:●P的路径长度必定为奇数,第一条边和最后一条边都不属于M。

●P经过取反操作可以得到一个更大的匹配M’。

●M为G的最大匹配当且仅当不存在相对于M的增广路径。

2、用增广路求最大匹配(称作匈牙利算法,匈牙利数学家Edmonds于1965年提出)。

算法轮廓:(1)置M为空(2)找出一条增广路径P,通过取反操作获得更大的匹配M’代替M(3)重复(2)操作直到找不出增广路径为止程序清单:Function find(k:integer):integer;var st,sf,i,j,t:integer;queue,father:array[1..100] of integer;beginqueue[1] := k; st := 1; sf := 1;fillchar(father,sizeof(father),0);repeatfor i:=1 to n doif (father[i]=0)and(a[queue[st],i]=1) thenbeginif match2[i]<>0 thenbegininc(sf);queue[sf] := match2[i];father[i] := queue[st];end elsebeginj := queue[st];while true dobegint := match1[j];match1[j] := i;match2[i] := j;if t = 0 then break;i := t; j := father[t];end;find := 1;exit;end;end;inc(st);until st>sf;find := 0;end;在主程序中调用下面的程序即可得出最大匹配数。

最大二分图匹配(匈牙利算法)

最大二分图匹配(匈牙利算法)

最大二分图匹配(匈牙利算法)二分图指的是这样一种图:其所有的顶点分成两个集合M和N,其中M或N中任意两个在同一集合中的点都不相连。

二分图匹配是指求出一组边,其中的顶点分别在两个集合中,并且任意两条边都没有相同的顶点,这组边叫做二分图的匹配,而所能得到的最大的边的个数,叫做最大匹配。

计算二分图的算法有网络流算法和匈牙利算法(目前就知道这两种),其中匈牙利算法是比较巧妙的,具体过程如下(转自组合数学):令g=(x,*,y)是一个二分图,其中x={x1,x2...},y={y1,y2,....}.令m为g中的任意匹配。

1。

将x的所有不与m的边关联的顶点表上¥,并称所有的顶点为未扫描的。

转到2。

2。

如果在上一步没有新的标记加到x的顶点上,则停,否则,转33。

当存在x被标记但未被扫描的顶点时,选择一个被标记但未被扫描的x的顶点,比如xi,用(xi)标记y 的所有顶点,这些顶点被不属于m且尚未标记的边连到xi。

现在顶点xi 是被扫描的。

如果不存在被标记但未被扫描的顶点,转4。

4。

如果在步骤3没有新的标记被标记到y的顶点上,则停,否则转5。

5。

当存在y被标记但未被扫描的顶点时。

选择y的一个被标记但未被扫描的顶点,比如yj,用(yj)标记x的顶点,这些顶点被属于m且尚未标记的边连到yj。

现在,顶点yj是被扫描的。

如果不存在被标记但未被扫描的顶点则转道2。

由于每一个顶点最多被标记一次且由于每一个顶点最多被扫描一次,本匹配算法在有限步内终止。

代码实现:bfs过程:#include<stdio.h>#include<string.h>main(){bool map[100][300];inti,i1,i2,num,num1,que[300],cou,stu,match1[100],match2[300],pqu e,p1,now,prev[300],n;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d%d",&cou,&stu);memset(map,0,sizeof(map));for(i1=0;i1<cou;i1++){scanf("%d",&num);for(i2=0;i2<num;i2++){scanf("%d",&num1);map[i1][num1-1]=true;}}num=0;memset(match1,int(-1),sizeof(match1)); memset(match2,int(-1),sizeof(match2)); for(i1=0;i1<cou;i1++){p1=0;pque=0;for(i2=0;i2<stu;i2++){if(map[i1][i2]){prev[i2]=-1;que[pque++]=i2;}elseprev[i2]=-2;}while(p1<pque){now=que[p1];if(match2[now]==-1)break;p1++;for(i2=0;i2<stu;i2++){if(prev[i2]==-2&&map[match2[now]][i2]){prev[i2]=now;que[pque++]=i2;}}}if(p1==pque)continue;while(prev[now]>=0){match1[match2[prev[now]]]=now; match2[now]=match2[prev[now]]; now=prev[now];}match2[now]=i1;match1[i1]=now;num++;}if(num==cou)printf("YES\n");elseprintf("NO\n");}}dfs实现过程:#include<stdio.h>#include<string.h>#define MAX 100bool map[MAX][MAX],searched[MAX]; int prev[MAX],m,n;bool dfs(int data){int i,temp;for(i=0;i<m;i++){if(map[data][i]&&!searched[i]){searched[i]=true;temp=prev[i];prev[i]=data;if(temp==-1||dfs(temp))return true;prev[i]=temp;}}return false;}main(){int num,i,k,temp1,temp2,job;while(scanf("%d",&n)!=EOF&&n!=0) {scanf("%d%d",&m,&k);memset(map,0,sizeof(map));memset(prev,int(-1),sizeof(prev)); memset(searched,0,sizeof(searched));for(i=0;i<k;i++){scanf("%d%d%d",&job,&temp1,&temp2); if(temp1!=0&&temp2!=0)map[temp1][temp2]=true;}num=0;for(i=0;i<n;i++){memset(searched,0,sizeof(searched)); dfs(i);}for(i=0;i<m;i++){if(prev[i]!=-1)num++;}printf("%d\n",num);}}。

二分图的完备匹配

二分图的完备匹配

这个算法的要点是把初始匹配通过可增广轨逐次增 广,以至得到最大匹配。然后根据有无未盖点来判 定这个最大匹配是否为完备匹配。 例如求图7—8(d)中的最大匹配, 设初始匹配M={(X2Y2,X3Y3,X5Y5} 以未盖点X1为根,生成交错树,结果得到可增广 轨X1Y2X2Y1(见)。
X1
X2
X3
X4
X5
Y1
Y2
Y3
Y4
Y5
X1
X2
X3
X4
X5
Y1
Y2
Y3
Y4
Y5
求二分图最佳匹配的算法——匈牙利算法 变量说明; S——外点集合,初始时为交错树的根; T——内点集合,初始时为空; N(S)——与S中的顶点相邻的顶点集合。显然,若N(S)= T,表明与任一外点相连的端点都在内点集合里,找不出一 条不属于交错树的边,图G无完备匹配; M——匹配边集合; E(P)——可增广轨P上的边。 · MOE(P)——进行对称差运算的结果,为可增广轨P上的 匹配边与非匹配边对换,P轨外的匹配边不变,使得M改进 成一个多包含一条边的匹配。
问是否能从g中得出一个不含未盖点的匹配这种将g的每一个顶点盖住的匹配称为二分图的完备匹可能存在完备匹配的图是否仅限于二分图呢
二分图的完备匹配

某公司有工作人员X1,X2,…,Xm,他们去做 工作Y1,Y2,…,Yn,每人适合做其中的一项或几 项工作,问能否每人都分配一项合适的工作。 这个问题的数学模型是:构造一个二分图G, 顶点划分为两个部分: 一个是工作人员集合X={Xl,X2,…,Xm}, 一个是工作集合Y={Y1,Y2,…,Yn}, 当且仅当Xi适合干工作Yi时,Xi与Yi之间连一条边。 问是否能从G中得出一个不含未盖点的匹配,这种 将G的每一个顶点盖住的匹配称为二分图的完备匹 配。

二分图的讲解

二分图的讲解
8
例 3个图的匹配数 依次为3, 3, 4.
4
匹配 (续)
设M为G中一个匹配 vi与vj被M匹配: (vi,vj)M v为M饱和点: M中有边与v关联 v为M非饱和点: M中没有边与v关联 M为完美匹配: G的每个顶点都是M饱和点
例 关于M1, a,b,e,d是饱和点 f,c是非饱和点
M1不是完美匹配
(1)
(2)
(3)
6
Hall定理
定理(Hall定理) 设二分图G=<V1,V2,E>中,|V1||V2|. G中存 在从V1到V2的完备匹配当且仅当V1中任意k 个顶点至少与V2 中的k个顶点相邻(k=1,2,…,|V1|). 由Hall定理不难证明, 上一页图(2)没有完备匹配.
定理 设二部图G=<V1,V2,E>中, 如果存在t1, 使得V1中每个 顶点至少关联 t 条边, 而V2中每个顶点至多关联t条边,则G 中存在V1到V2的完备匹配.
注意: n 阶零图为二分图.
2
二分图的判别法
定理 非平凡无向图G=<V,E>是二分图当且仅当G中 无奇数长度的回路
例 下述各图都是二分图
3
匹配
设G=<V,E>, 匹配(边独立集): 任2条边均不相邻的边子集 极大匹配: 添加任一条边后都不再是匹配的匹配 最大匹配: 边数最多的匹配
匹配数: 最大匹配中的边数, 记为1
M2是完美匹配
M1
M2
5
二分图中的匹配
定义 设G=<V1,V2,E>为二部图, |V1||V2|, M是G中最 大匹配, 若V1中顶点全是M饱和点, 则称M为G中V1 到V2的完全匹配. 当|V1|=|V2|时, 完备匹配变成完美 匹配.

二分图最大匹配及常用建图方法

二分图最大匹配及常用建图方法

算法———艺术二分图匹配剖析很多人说,算法是一种艺术。

但是对于初学者的我,对算法认识不是很深刻,但偶尔也能感受到他强大的魅力与活力。

这让我追求算法的脚步不能停止。

下面我通过分析匈牙利算法以及常用建图方式,与大家一起欣赏算法的美。

匈牙利算法匈牙利算法是用来解决最大二分图匹配问题的,所谓二分图即“一组点集可以分为两部分,且每部分内各点互不相连,两部分的点之间可以有边”。

所谓最大二分图匹配即”对于二分图的所有边,寻找一个子集,这个子集满足两个条件,1:任意两条边都不依赖于同一个点。

2:让这个子集里的边在满足条件一的情况下尽量多。

首先可以想到的是,我们可以通过搜索,找出所有的这样的满足上面条件的边集,然后从所有的边集中选出边数最多的那个集合,但是我们可以感觉到这个算法的时间复杂度是边数的指数级函数,因此我们有必要寻找更加高效的方法。

目前比较有效的方法有匈牙利算法和通过添加汇点和源点的网络流算法,对于点的个数都在200 到300 之间的数据,我们是采取匈牙利算法的,因为匈牙利算法实现起来要比网络流简单些。

下面具体说说匈牙利算法:介绍匈牙利之前,先说说“增广轨”。

定义:若P是图G中一条连通两个未匹配顶点的路径,并且属最大匹配边集M的边和不属M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广轨定义总是抽象的下面通过图来理解它。

图中的线段(2->3, 3->1, 1->4)便是上面所说的p路径,我们假定边(1,3)是以匹配的边,(2,3)(1,4)是未匹配的边,则边(4,1)边(1,3)和边(3,2)在路径p上交替的出现啦,那么p就是相对于M的一条增广轨,这样我们就可以用边1,4 和边2,3来替换边1,3 那么以匹配的边集数量就可以加1,。

匈牙利算法就是同过不断的寻找增广轨实现的。

很明显如果二分图的两部分点分别为n 和m,那么最大匹配的数目应该小于等于MIN(n,m); 因此我们可以枚举任第一部分(的二部分也可以)里的每一个点,我们从每个点出发寻找增广轨,最后吧第一部分的点找完以后,就找到了最大匹配的数目,当然我们也可以通过记录找出这些边。

离散数学中的图的匹配和二分图

离散数学中的图的匹配和二分图

在离散数学中,图论是一门重要的理论基础课程,它研究的是由节点和边构成的图结构。

图的匹配和二分图是图论中的两个重要概念,它们在现实生活中有着广泛的应用。

首先,我们来介绍一下图的匹配。

图的匹配指的是在一个图中选取一些边,使得这些边彼此不相交,即任意两条边不共享同一个顶点。

图的匹配问题可以用最优化问题来描述,既需要满足匹配条件,还需要满足某种优化目标。

例如,在一个社交网络图中,选择一些用户与其他用户进行配对,使得两个不认识的用户不会被配对在一起,同时目标是使得配对用户的兴趣爱好相似度最大化。

在这个问题中,边表示用户之间是否认识,而边的权值表示兴趣爱好的相似度。

其次,我们来介绍一下二分图。

二分图是一种特殊的图结构,它可以被划分为两个独立的顶点集合,使得同一个顶点集合内的顶点之间没有边相连。

换句话说,二分图中不存在奇圈。

二分图的一个典型例子是婚姻匹配问题。

假设有n个男性和n个女性,他们之间有多种可能的配对方式,但是每个人只能与另一个不同性别的人结婚。

这时,我们可以用一个二分图来表示这个问题,其中男性和女性分别作为两个顶点集合,边表示可能的配对。

然后,我们可以使用图的匹配算法来找到一个最佳匹配方案。

图的匹配和二分图在离散数学中有着重要的研究价值和应用价值。

首先,图的匹配可以用于解决资源分配问题。

例如,在一个工厂中,有m个任务需要分配给n个员工进行处理,每个员工对某些任务有一定的能力要求,而每个任务也需要一定的时间完成。

这时,我们可以将员工和任务分别作为两个顶点集合,边的权值表示员工对任务的能力是否满足要求和任务完成时间。

然后,我们可以使用图的匹配算法来找到一个最佳的任务分配方案,使得员工的工作量最小。

其次,二分图可以用于解决社交网络分析问题。

如今,社交网络已经成为人们日常生活中重要的一部分,人们之间通过社交网络平台进行交流和连接。

我们可以使用二分图来表示社交网络的结构,其中一个顶点集合表示用户,另一个顶点集合表示用户之间的好友关系,边的权值表示用户之间的相似性度量。

离散数学_二分图与匹配

离散数学_二分图与匹配

二分图与匹配
满足如下条件的无向图G=<V,E>有非空集合X,Y:X∪Y=V,X∩Y=∅,且每个vᵢ ,vⱼ∈E,都有:vᵢ∈X∧vⱼ∈Y,或者vᵢ∈Y∧vⱼ∈X可以用G=<X,E,Y>表示二分图
完全二分图 : 如果X,Y中任意两个顶点之间都有边,则称为完全二分图
匹配 : 将E的子集M称作一个匹配
最大匹配 : 如果M中的任意两条边都没有公共端点边数最多的匹配称作最大匹配
完全匹配 : 如果X(Y)中的所有的顶点都出现在匹配M中,则称M是X(Y)-完全匹配 如果M既是X-完全匹配,又是Y-完全匹配,称M是完全匹配最大匹配匈牙利算法 : ①任意取一个匹配M (可以是空集或只有一条边) ②令S是非饱和点(尚未匹配的点)的集合 ③如果S=∅,则M已经是最大匹配 ④从S中取出一个非饱和点u₀作为起点,从此起点走交错路(交替属于M和非M的边构成的极大无重复点通路或回路)P ⑤如果P是一个增广路(P的终点也是非饱和点),则令M=M⊕P=(M-P)∪(P-M) ⑥如果P都不是增广路,则从S中去掉u₀,转到step3。

二分图与匹配_黄哲威

二分图与匹配_黄哲威

CF1268B. Domino for Young
对格子子进行行行黑黑白白染色色,答案是两种格子子数量量的较小小值
考虑建二二分图,容易易证明匹配一一定可以配满,因为任意一一个白白格到 任意一一个黑黑格之间都能找一一个增广广路路
CF623A.Graph and String
n 个结点的无无向图,每个结点标号”abc” 三个字⺟母其中一一个。
随便便选一一个点,染成白白色色,然后把它相邻的点染成黑黑色色,再把 这些点相邻的点染成黑黑色色,以此类推。
用用 dfs 或者 bfs 实现这个过程。
如果染色色过程中有矛矛盾,说明这个图不不是二二分图。
匈牙牙利利算法
把二二分图分为 A, B 两个集合,依次枚举 A 中的每个点, 试图在B集合中找到一一个匹配。
这就是匈牙牙利利算法的过牙利利算法
顶点覆盖和独立立集
定义:假如选了了一一个点就相当于覆盖了了以它为端点的所有边。最小小顶 点覆盖就是选择最少的点来覆盖所有的边。
定理理:最小小顶点覆盖等于二二分图的最大大匹配。
设最大大匹配是M,考虑最小小顶点覆盖:
(1)M个点是足足够的。就是说他们覆盖最大大匹配的那M条边后,假设 有某边 e 没被覆盖,那么把 e 加入入后会得到一一个更更大大的匹配,出现矛矛 盾。
练习题
CF-gym-101755D. Transfer Window
n 个球员,有 m 个关系,表示某个球员可以换成另外一一个球员。现 在有某 K 个球员,想要 K 个其它球员(可能已经有了了可能没有), 问是否有交换方方案。
n <= 300, m <= 90000
CF-gym-101755D. Transfer Window
改变限制,要求 2i 和 2i − 1 ⻝食食物类型不不同

用匈牙利算法求二分图的最大匹配.

用匈牙利算法求二分图的最大匹配.

一、用匈牙利算法求二分图(二部图,偶图的最大匹配算法中的几个术语说明:1。

二部图:如果图G=(V,E的顶点集何V可分为两个集合X,Y,且满足X∪Y =V, X∩Y=Φ,则G称为二部图;图G的边集用E(G表示,点集用V(G表示。

2。

匹配:设M是E(G的一个子集,如果M中任意两条边在G中均不邻接,则称M是G的一个匹配。

M中的—条边的两个端点叫做在M是配对的。

3。

饱和与非饱和:若匹配M的某条边与顶点v关联,则称M饱和顶点v,并且称v是M-饱和的,否则称v是M-不饱和的。

4。

交互道:若M是二分图G=(V,E的一个匹配。

设从图G中的一个顶点到另一个顶点存在一条道路,这条道路是由属于M的边和不属于M的边交替出现组成的,则称这条道路为交互道。

5。

可增广路:若一交互道的两端点为关于M非饱和顶点时,则称这条交互路是可增广路。

显然,一条边的两端点非饱和,则这条边也是可增广路。

6。

最大匹配:如果M是一匹配,而不存在其它匹配M',使得|M'|>|M|,则称M是最大匹配。

其中|M|表示匹配M的边数。

7。

对称差:A,B是两个集合,定义A⊕B = (A∪B\(A∩B ,则称A⊕B为A和B的对称差。

定理:M为G的最大匹配的充要条件是G中不存在可增广道路。

Hall定理:对于二部图G,存在一个匹配M,使得X的所有顶点关于M饱和的充要条件是:对于X的任意一个子集A,和A邻接的点集为T(A,恒有:|T(A| >= |A|。

匈牙利算法是基于Hall定理中充分性证明的思想,其基本步骤为:1。

任给初始匹配M;2。

若X已饱和则结束,否则进行第3步;3。

在X中找到一个非饱和顶点x0,作V1 ←{x0},V2 ←Φ ;4。

若T(V1 = V2则因为无法匹配而停止,否则任选一点y∈T(V1\V2;5。

若y已饱和则转6,否则做一条从x0→y的可增广路P,M←M⊕E(P,转2;6。

由于y已饱和,所以M中有一条边(y,z,作V1 ←V1∪{z}, V2←V2∪{y},转4;二、用匈牙利算法求二分图的最大匹配(伪代码给定一个二分图(x,y,x中的点和y中点的连接情况,一个匹配是二分图的子图,其中任一个x中的点只能和最多一个y中的点连接,一个y中的点也只能和一个x中的点连接,最大匹配就是使子图中的边数(我们称为匹配边最多的匹配。

基于二分图匹配的任务分配算法

基于二分图匹配的任务分配算法

基于二分图匹配的任务分配算法在现代的科技发展中,任务分配算法是一个非常重要的领域。

它可以帮助我们在许多领域中提高效率和减少成本。

其中,在商业领域、工业领域和科学领域等方面,任务分配算法都有着极其广泛的应用。

而基于二分图匹配的任务分配算法是其中一种比较常见的方法。

首先,什么是二分图?简单来说,二分图就是一种特殊的图形结构。

在二分图中,所有的结点被分为两个部分,而两个部分之间的边只存在于不同的部分之间。

此外,在一张二分图中,不存在连向同一部分中的两个结点的边。

在二分图中进行任务分配的基本思路就是将任务和执行者分别作为两个部分的结点,并且需要保证任务和执行者之间一一对应。

也就是说,一个执行者只能处理一个任务,而一个任务也只能指定一个执行者进行处理。

这样一来,任务和执行者之间的匹配就可以通过二分图进行处理。

二分图匹配的常用算法有很多,而其中比较常见的算法是匈牙利算法。

匈牙利算法的基本思路是通过不断寻找增广路的方法来不断扩展前一个匹配的结果。

在匈牙利算法中,每个执行者都会依次尝试处理任务,如果任务还没有被其他执行者处理,并且执行者有能力处理该任务,那么该任务就会被分配给该执行者。

如果任务已经被其他执行者分配了,那么该执行者就会尝试寻找其他任务,直到找到自己可以处理的任务为止。

如果该执行者无法找到自己可以处理的任务,那么他就会放弃这一轮任务分配。

通过这种方式,匈牙利算法能够保证任务和执行者之间始终保持一一对应关系,从而实现高效的任务分配。

除了匈牙利算法,基于二分图匹配的任务分配算法还有很多其他的方法。

例如,可以通过网络流算法来解决二分图匹配问题。

在网络流算法中,二分图中的每个结点都被视为一个顶点,并且每个顶点之间的边都被赋予一个流量值。

通过不断调整流量值,网络流算法可以找到最优的任务分配方案。

此外,还可以使用线性规划算法、遗传算法等其他算法来解决二分图匹配问题。

不同的算法有不同的优点和适用范围,具体选择哪种算法需要根据具体的应用场景来决定。

二分图的匹配

二分图的匹配

第九章二分图中的匹配三个典型问题:(1)在一个有禁止位置的m×n棋盘上,能放置非攻击型车的最多个数是多少?(2)在一个有禁止位置的m×n棋盘上,能放置多米诺牌覆盖的最多个数是多少?(3)一个公司有n个工作空缺,需要有一定技能的人填补,同时有m个人申请这些项工作,每人能胜任n项工作中的若干项,问最多有多少项工作能找到合适的人选?9.1 一般的问题描述定义1:令X={x1, x2, …,x m}, Y={y1,y2, …,y n},且X∩Y=Ф,而△是序偶e=(x,y)的集合,其中x ∈X,y∈Y,那么三元组G=(X,△,Y)称作二分图。

定义2:令G=(X,△,Y)是一个二分图,边集△的子集M,若M中没有两条边存在公共点,称M是二分图G的一个匹配。

定义3:设G是一个二分图,定义ρ(G)={∣M∣:M是G的一个匹配}为二分图G的最大匹配边数。

9.2 匹配定义1:G=(X,△,Y),X={x1, x2, …,x m}, Y={y1,y2, …,y n},满足∣M*∣=ρ(G)的匹配M*称为二分图G的最大匹配。

一般M*不唯一,且∣M*∣=ρ(G)≤min{m,n}。

寻找M*的困难点:(1)若已知ρ(G),那么遍历所有可能的匹配会找到M*,但搜索量巨大;(2)一般ρ(G)并不事先知道,要找到M*,并求出ρ(G)=∣M*∣难度更大。

定义2:令u和v是二分图G=(X,△,Y)的任意两个顶点,连接u和v的互异顶点序列:γ:u=u0, u1, u2, …, u p-1, u p=v使得任意两个相邻顶点有一条边连接,即:{ u0, u1},{ u1, u2},…, { u p-1, u p}∈△,那么称序列γ为二分图G的一个链。

链长等于序列的边数p,若u=v, 链γ也叫圈。

定义3:令M为二分图G=(X,△,Y)中的一个匹配,令M是M的补集,即G的不属于M的边集合,M∪M=△。

令u和v是顶点,且u和v一个是左顶点(即属于X),一个是右顶点(即属于Y),若连接u和v的链满足下列性质:(1)γ的第一、三、五、、、边属于M;(2)γ的第二、四、六、、、边属于M;(3)u和v都不与M的边相连。

二分图最大匹配:匈牙利算法的python实现

二分图最大匹配:匈牙利算法的python实现

⼆分图最⼤匹配:匈⽛利算法的python实现⼆分图匹配是很常见的算法问题,⼀般⽤匈⽛利算法解决⼆分图最⼤匹配问题,但是⽬前⽹上绝⼤多数都是C/C++实现版本,没有python版本,于是就⽤python实现了⼀下深度优先的匈⽛利算法,本⽂使⽤的是递归的⽅式以便于理解,然⽽迭代的⽅式会更好,各位可以⾃⾏实现。

1、⼆分图、最⼤匹配什么是⼆分图:⼆分图⼜称作⼆部图,是图论中的⼀种特殊模型。

设G=(V,E)是⼀个⽆向图,如果顶点V可分割为两个互不相交的⼦集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为⼀个⼆分图。

什么是匹配:把上图想象成3位⼯⼈和4种⼯作,连线代表⼯⼈愿意从事某项⼯作,但最终1个⼯⼈只能做⼀种⼯作,最终的配对结果连线就是⼀个匹配。

匹配可以是空。

什么是最⼤匹配:在愿意从事的基础上,能够最多配成⼏对。

现在要⽤匈⽛利算法找出最多能发展⼏对。

[color=green][size=medium]匈⽛利算法是解决寻找⼆分图最⼤匹配的。

更多⼆分图最⼤匹配的图解可以参考 /5576502/1297344以下是代码,为了图省事使⽤了类,实际上并不需要这样M=[]class DFS_hungary():def__init__(self, nx, ny, edge, cx, cy, visited):self.nx, self.ny=nx, nyself.edge = edgeself.cx, self.cy=cx,cyself.visited=visiteddef max_match(self):res=0for i in self.nx:if self.cx[i]==-1:for key in self.ny: # 将visited置0表⽰未访问过self.visited[key]=0res+=self.path(i)return resdef path(self, u):for v in self.ny:if self.edge[u][v] and (not self.visited[v]):self.visited[v]=1if self.cy[v]==-1:self.cx[u] = vself.cy[v] = uM.append((u,v))return 1else:M.remove((self.cy[v], v))if self.path(self.cy[v]):self.cx[u] = vself.cy[v] = uM.append((u, v))return 1return 0ok,接着测试⼀下:if__name__ == '__main__':nx, ny = ['A', 'B', 'C', 'D'], ['E', 'F', 'G', 'H']edge = {'A':{'E': 1, 'F': 0, 'G': 1, 'H':0}, 'B':{'E': 0, 'F': 1, 'G': 0, 'H':1}, 'C':{'E': 1, 'F': 0, 'G': 0, 'H':1}, 'D':{'E': 0, 'F': 0, 'G': 1, 'H':0}} # 1 表⽰可以匹配, 0 表⽰不能匹配cx, cy = {'A':-1,'B':-1,'C':-1,'D':-1}, {'E':-1,'F':-1,'G':-1,'H':-1}visited = {'E': 0, 'F': 0, 'G': 0,'H':0}print DFS_hungary(nx, ny, edge, cx, cy, visited).max_match()结果为4,是正确的。

二分图及匹配算法

二分图及匹配算法

Chapter 3
二分图最佳匹配
-二分图最佳匹配-
定义:图G中权值和最大的完全匹配。
Kuhn-Munkras算法:该算法是通过给每个顶点一个标号(叫做顶标) 来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点Xi的顶标 为A[ i ],顶点Yj的顶标为B[ j ],顶点Xi与Yj之间的边权为w[i,j]。在算法 执行过程中的任一时刻,对于任一条边(i,j),A[ i ]+B[j]>=w[i,j]始终成立。 KM算法的正确性基于以下定理: 若由二分图中所有满足A[ i ]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等 子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。 KM算法流程: (1)初始化可行顶标的值; (2)用匈牙利算法寻找完备匹配; 这样做是O(n^4)的
-稳定婚姻问题-
Байду номын сангаас
求婚拒绝算法(Gale-Shapley算法/延迟认可算法): 先对所有男生进行单身标记,称其为单身狗男。当存在单身狗男时,进行 以下操作:
①选择一位单身狗男在所有尚未拒绝她的女生中选择一位被他排名最优先 的女神;
②女神将正在追求她的单身狗男与其现任进行比较,选择其中排名优先的 男生作为其男友,即若单身狗男优于现任,则现任被抛弃为前任;否则保 留其男友,拒绝单身狗男。 ③若某男生被其女友抛弃,则重新变成单身狗男,至①重复。
Chapter 5
稳定婚姻问题
-稳定婚姻问题-
你们班上有n位男生和n位女生,每个人对异性都有一个排序,表示对他们 的爱恋程度。现在你的任务是使他们凑成CP,使他们的爱情坚不可摧! 满足一下条件的爱情不是坚不可摧的: 男生u和女生v不是CP,但他们爱恋对方的程度都大于爱恋现任 的程度。 因为这样男生u和女生v会抛下已经是CP的那个她/他,另外组成一对。于 是乎多出了两位前任,这样就会让人再也无法相信爱情了! 怎么能避免悲剧的发生呢?

ACM讲课之二分图匹配(匈牙利算法)ppt课件

ACM讲课之二分图匹配(匈牙利算法)ppt课件

1
1
1
2
2
3
323Fra bibliotek44
5
可编辑课件PPT
5
11
i = 3时: Pre[1] = 3;
1 2 3 4 5
可编辑课件PPT
1 1
2
3
4
5
12
i = 4时 : Pre[3] = 2; Pre[2] = 1; Pre[5] = 3; Pre[1] = 4;
1 2 3 4 5
可编辑课件PPT
1 2 3 4
匹配1
v1
v2
v3
匹配2
v1
v2
v3
v4
v5
v4
v5
可编辑课件PPT
3
二分图的最大匹配
最大匹配:图中包含边数最多的匹配称为图的最大匹配。
今天我要讲的是无权二分图的最 大匹配问题,采用匈牙利算法。
可编辑课件PPT
4
匈牙利算法必备知识:
1.盖点:有被M中的边关联到的节点,未盖点则相反。
2.增广路径:若二分图中有一条路径p,其起始点和结束点都是未盖 点,其间属于M的边和不属于M的边交替出现,则称路径p是一条关于 M的增广路径。
5
13
二分图最大匹配延伸
最小点覆盖 最小边覆盖 最大独立集 有向图最小路径覆盖 最优匹配(KM算法)
可编辑课件PPT
14
此课件下载可自行编辑修改,此课件供参考! 部分内容来源于网络,如有侵权请与我联系删除!感谢你的观看!
匈牙利算法: 计算二分图最大匹配就是应用增广路径的概念,每次寻找一条关于M 的增广路径p,通过M和增广路径进行异或,使得M中的匹配数增加1 。以此类推,直至二分图中不存在关于M的增广路径为止。此时得到 匹配M就是图G的一个最大匹配。

主要定理二分图的最大匹配算法二分图的带权重的最大匹配

主要定理二分图的最大匹配算法二分图的带权重的最大匹配

2021/2/13
山东大学 软件学院
22
时间复杂度分析
令|S| = m,|T| = n,假设 m n。 找一条增广路(或判断不能找到)标号算法最多进行 O(mn)
次检查(因为最多有这么多条边)。 初始匹配最多被增广 m 次。 所以,总的计算量为 O(m2n)。
2021/2/13
山东大学 软件学院
2021/2/13
山东大学 软件学院
17
例子
1
6
2
72
3
82
4
9
5
10
找到一条增广路(2, 8)。更新M。
2021/2/13
山东大学 软件学院
18
例子
1
63
2
7
3
83
4
93
5
10 3
找到一条增广路(3, 10)。更新M。
2021/2/13
山东大学 软件学院
19
例子
2021/2/13
1 2 10 3 4 5
2021/2/13
山东大学 软件学院
4
例子
2021/2/13
山东大学 软件学院
5
定理
定理:记G’上的最大流为f*,流值为|f*|。G上的最大匹配 为M*。则|f*| = |M*|。 证明:首先证|f*| |M*|。 给定最大匹配M*,令G’上M*中的边的流值为1,s到M*匹 配的V一侧点的各条边上流值为1,M*匹配的U一侧点到t的 各条边上流值为1,则构造了一个流值为|M*|的流f。 因此,显然有|f*| |M*|。 再证|f*| |M*|。 设f*为G’上的最大流。 由整流定理,G’上每条边上的流值为整数。由于每条边的 容量均为1,因此G’上每条边的流值不是0就是1。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

9.1 二 分 图9.1.1 二分图的基本概念定义9.1 无向图G = <V,E,Y>称为二分图(bipartite graph),如果有非空集合X,Y使X∪Y = V,X∩Y =φ,且对每一e∈E,Y(e) = (x, y),x∈X,y∈Y。

此时常用<X,E,Y>表示二分图G。

若对X中任一x及Y中任一y恰有一边e∈E,使Y(e) = (x, y), 则称G为完全二分图(complete bipartite graph)。

当|X| = m,|Y| = n时,完全二分图G记为K m,n。

简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集。

例9.1 图9.1中(a),(b)为二分图,(c)为完全二分图K3,3,(d), (e)不是二分图。

二分图的下列特征性是重要的。

定理9.1 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。

证 先证必要性。

设G为二分图<X,E,Y>。

由于X,Y非空,故G至少有两个顶点。

若C 为G中任一回路,令C = ( v0,v 1,v2,…,v l-1,v l = v0 )其中诸v i ( i = 0,1,…,l )必定相间出现于X及Y中,不妨设{v0,v2,v4,…, v l = v0} Í X{v1,v3,v5,…, v l-1} Í Y因此l必为偶数,从而C中有偶数条边。

再证充分性。

设G的所有回路具有偶数长度,并设G为连通图(不失一般性,若G 不连通,则可对G的各连通分支作下述讨论)。

令G的顶点集为V,边集为E,现构作X,Y,使<X,E,Y> = G。

取v0ÎV,置X = {v | v= v0或v到v0有偶数长度的通路}Y = V-XX显然非空。

现需证Y非空,且没有任何边的两个端点都在X中或都在Y 中。

由于|V|≥2并且G为一连通图,因此v0必定有相邻顶点,设为v1,那么v1ÎY;故Y不空。

设有边(u, v), 使uÎX,vÎX。

那么,v0到u有偶数长度的通路,或u = v0;v0到v有偶数长度的通路,或v = v0。

无论何种情况,均有一条从v0到v0的奇数长度的闭路径,因而有从v0到v0的奇数长度的回路(因从闭路径上可能删去的回路长度总为偶数),与题设矛盾。

故不可能有边(u, v)使u, v均在X中。

“没有任何边的两个端点全在Y中”的证明可仿上进行,请读者思考。

二分图是十分有用的一种数学模型,许多问题可以用它来刻划。

例如“资源分配”、“工作安排”、“人员择偶”等等。

但是,利用二分图分析解决这类问题时,还需要有关二分图的另一个概念——匹配。

匹配定义9.2设G = <X,E,Y>为二分图,M∈E。

称M为G的一个匹配(matching),如果M中任何两条边都没有公共端点。

G的所有匹配中边数最多的匹配称为最大匹配(maximal matching)。

如果X(Y)中任一顶点均为匹配M中边的端点,那么称M为X(Y)-完全匹配(perfect matching)。

若M既是X-完全匹配又是Y-完全匹配,则称M为G的完全匹配。

例9.2图9.2中各图的粗线表示匹配中的边(简称匹配边)。

(b)中匹配是最大的,X-完全的,(c)中匹配是完全的(从而也是最大的)。

注意,最大匹配总是存在但未必唯一。

此外,X(Y)-完全匹配及完全匹配必定是最大的,但反之则不然;X(Y)-完全匹配未必存在。

为讨论最大匹配的求法及完全匹配的存在条件,需要下列术语。

定义9.3设G = <X,E,Y>,M为G的一个匹配。

(1)M中边的端点称为M-顶点,其它顶点称为非M-顶点。

(2)G中v k到v l的通路P称为交替链,如果P的起点v k和终点v l为非M-顶点,而其边的序列中非匹配边与匹配边交替出现(从而首尾两边必为非匹配边,除顶点v k,v l以外各顶点均为M-顶点)。

特别地,当一边(v, v')两端点均为非M-顶点,通路(v, v')亦称为交替链。

匈牙利算法以下算法可把G中任一匹配M扩充为最大匹配,此算法是Edmonds 于1965年提出的,被称为匈牙利算法,其步骤如下:(1)首先用(*)标记X中所有的非M-顶点,然后交替进行步骤(2),(3)。

(2)选取一个刚标记(用(*)或在步骤(3)中用(y i)标记)过的X中顶点,例如顶点x i,然后用(x i)去标记Y中顶点y,如果x i与y为同一非匹配边的两端点,且在本步骤中y尚未被标记过。

重复步骤(2),直至对刚标记过的X中顶点全部完成一遍上述过程。

(3)选取一个刚标记(在步骤(2)中用(x i)标记)过的Y中结点,例如y i,用(y i)去标记X中结点x,如果y i与x为同一匹配边的两端点,且在本步骤中x尚未被标记过。

重复步骤(3),直至对刚标记过的Y中结点全部完成一遍上述过程。

(2),(3)交替执行,直到下述情况之一出现为止:(Ⅰ)标记到一个Y中顶点y,它不是M-顶点。

这时从y出发循标记回溯,直到(*)标记的X中顶点x,我们求得一条交替链。

设其长度为2k+1,显然其中k条是匹配边,k+1条是非匹配边。

(Ⅱ)步骤(2)或(3)找不到可标记结点,而又不是情况(Ⅰ)。

(4)当(2),(3)步骤中断于情况(Ⅰ),则将交替链中非匹配边改为匹配边,原匹配边改为非匹配边(从而得到一个比原匹配多一条边的新匹配),回到步骤(1),同时消除一切现有标记。

(5)对一切可能,(2)和(3)步骤均中断于情况(Ⅱ),或步骤(1)无可标记结点,算法终止(算法找不到交替链)。

我们不打算证明算法的正确性,只用一个例子跟踪一下算法的执行,来直观地说明这一点。

例9.3 用匈牙利算法求图9.3的一个最大匹配。

(1)置M = Æ,对x1-x6标记(*)。

(2)找到交替链(x1, y1)(由标记(x1),(*)回溯得),置M = {(x1, y1)}。

(3)找到交替链(x2, y2)(由标记(x2),(*)回溯得),置M = {(x1, y1), (x2, y2),}。

(4)找到交替链(x3, y1, x1, y4)(如图9.4所示。

图中虚线表示非匹配边,细实线表示交替链中非匹配边,粗实线表示匹配边),因而得M = {(x2, y2), (x3, y1),(x1, y4)}。

(5)找到交替链(x4, y3)(由标记(x4),(*)回溯得),置M = {(x2, y2), (x3, y1),(x1, y4), (x4, y3)}。

(6)找到交替链(x5, y4, x1, y1, x3, y7)(如图9.5所示,图中各种线段的意义同上),因而得M = {(x2, y2), (x4, y3),(x5, y4), (x1, y1), (x3, y 7)}即为最大匹配(如图9.6所示)。

图9.6霍尔婚姻定理(完全匹配的存在条件)现在我们来讨论完全匹配的存在条件。

为此,定义图G = <V,E,Y>的顶点子集SÍV的相邻顶点集N(S)(所有与S中顶点相邻的顶点组成的集合):N(S) = {v | vÎV∧$u$e(uÎS∧eÎE∧Y(e) = (u, v))}或N(S) = {v | $u$e(uÎS∧Y(e) = (u, v))}定理9.2设图G = <X,E,Y>。

G有X-完全匹配的充分必要条件是:对每一SÍX有|N(S)|≥| S |此定理是霍尔(Hall)于1935年证明的,通常称为霍尔婚姻定理。

证必要性是易证的。

设G有X-完全匹配{(x0, y i0), (x1, y i1),…,(x m, y im)} ( m = | X | )其中诸x i互不相同,诸y ij也各不一样,因此对任一SÍX,S中有多少元素,N(S)中至少也有同样多的元素,即 |N(S)|≥| S |。

现证充分性。

设G满足:对任一SÍX,|N(S)|≥| S |,但G无X-完全匹配。

作G的最大匹配M,据假设,至少有顶点xÎX,x不是M-顶点。

用匈牙利算法求起始于x的所有交替链。

由于M已是最大匹配,上述构作过程必定在步骤(3)中因情况(Ⅱ)停止,即它们都只能是末尾边为匹配边的链(暂称伪交替链)。

用Q表示这些伪交替链上的顶点集合,易知,Q中只有x不是M-顶点。

置S = Q∩X,S'= Q∩Y(参阅图9.7)图9.7显然,S - {x}中顶点与S'中顶点一一对应,因此| S'| = | S | - 1S'ÍN(S)事实上N(S) = S',因为对每一yÎN(S),都有顶点uÎS = Q∩X(因而uÎQ)使(u, y)为一伪交替链中的边,从而yÎQ,即yÎQ∩Y=S'之中。

据以上讨论,|N(S)| = | S'| = | S | - 1|N(S)| < | S |与题设矛盾,因此M必是X-完全匹配。

定理9.2证毕。

对Y-完全匹配有类似的结论,不赘述。

相关文档
最新文档