二分图的匹配和图论
图论——二分图1:二分图以及判定

图论——⼆分图1:⼆分图以及判定图,有有向图,⽆向图,稠密图,简单图······算法,有贪⼼法,⼆分法,模拟法,倍增法······那,⼆分图是啥?⼆分法+有向图?于是,我查了许多资料,才对它有⼀定了解。
⼆分图:⼆分图,是图论中的⼀种特殊模型,设G=(V,E)是⼀个⽆向图,如果顶点V可分割为两个互不相交的⼦集(A,B),并且同⼀集合中不同的两点没有边相连。
这就是⼆分图。
举个栗⼦吧:这是不是⼆分图?反正我第⼀次看觉得不是其实,是的,他是⼆分图,尽管看上去是连着的。
若我们将图中的⼀些边转⼀下,变成:这就是⼀个明显的⼆分图。
集合A与B中的点互不相连。
因此,在⼿动判定⼆分图时学会转边!辣魔,⼆分图要⽤计算机判定怎么实现?数竞⼤佬:简单!!!!染⾊⼤法!!!有没有熟悉的感觉0表⽰还未访问,1表⽰在集合A中,2表⽰在集合B中。
col(color)储存颜⾊。
初始化为0.上代码:其实是模板可以记忆。
1 vector <int> v[N];2void dfs(int x,int y){3 col[x]=y;4for (int i=0; i<v[x].size(); i++) {5if (!col[v[x][i]]) dfs(v[x][i],3-y);6if (col[v[x][i]]==col[x]) FLAG=true; //产⽣了冲突7 }8 }9for (i=1; i<=n; i++) col[i]=0; //初始化10for (i=1; i<=n; i++) if (!col[i]) dfs(i,1); //dfs染⾊11if (FLAG) cout<<"NO"; else cout<<"YES";下⼀章我们将讲到⼆分图的匹配,我们明天见。
图论:二分图多重匹配

图论:⼆分图多重匹配使⽤最⼤流和费⽤流解决⼆分图的多重匹配之前编辑的忘存了好⽓啊。
本来打算学完⼆分图的乱七⼋糟的匹配之后再去接触⽹络流的,提前撞到了之前我们说的⼆分图最⼤匹配和⼆分图最⼤权匹配有⼀个特点,那就是没个点只能与⼀条边相匹配如果规定⼀个点要与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 }据说这是典型的最⼤流题⽬,然⽽为了强⾏安利⼀波⼆分图的多重匹配,就不说成那个了。
二分图理论

*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算法用来解决最大权匹配问题:在一个二分图内,左顶点为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]都没有变化。
数学建模图论模型

任意两点均有通路的图称为连通图。
连通而无圈的图称为树,常用T=<V,E>表示树。
若图G’是图 G 的生成子图,且G’又是一棵树, 则称G’是图G 的生成树。
例 Ramsey问题
图1
图2
并且常记: V = v1, v2, … , vn, |V | = n ; E = {e1, e2, … , em}ek=vivj , |E | = m
称点vi , vj为边vivj的端点 在有向图中, 称点vi , vj分别为边vivj的 始点和终点. 该图称为n,m图
8
对于一个图G = V, E , 人们常用图形来表示它, 称其 为图解 凡是有向边, 在图解上都用箭头标明其方向.
4、P'代替P,T'代替T,重复步骤2,3
定理2 设 T为V的子集,P=V-T,设 (1)对P中的任一点p,存在一条从a到p的最短路径,这条路径仅有P中的
点构成, (2)对于每一点t,它关于P的指标为l(t),令x为最小指标所在的点, 即:
l(x)mli(tn )} t{ ,T
(3)令P’=P Ux,T’=T-{x},l’(t)表示T'中结点t关于P'的指标,则
解:用四维01向量表示人,狼,羊,菜例在过河西河岸问的题状态(在
岸则分量取1;否则取0),共有24 =16 种状态; 在河东岸 态类似记作。
由题设,状态(0,1,1,0),(0,0,1,1),(0,1,1,1)是不允许的
其对应状态:(1,0,0,1), (1,1,0,0),(1,0,0,0)也是不允许
二分图匹配

二分图匹配一、二分图的概念二分图又称作二部图,是图论中的一种特殊模型。
设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;在主程序中调用下面的程序即可得出最大匹配数。
数学建模-二分图匹配

解题思路:本题是一道典型的二分图最大匹配 题。采用匈牙利算法。本题的构图是这样的, 左右两边的x和y,分别是x学生,y课程。那么 已知哪些学生可以学哪些课,也就是在x的点 和 y的点之间首先连上线。求xy的最大匹配。如果 有P个学生做了课代表,那么就是P门课程都有 课代表了。
例题1 Courses(hdu1006)
X学生
1 2 3
Y课程
1 2 3
样例 3
(1)建图
3 3 1 2 3 2 1 2 1 1
例题1 Courses(hdu1006)
X学生
1 2 3
Y课程
1 2 3
X学生
1 2 3
Y课程
1 2 3 连接 x1-y1 x2-y2 得到此 匹配, 匹配数 为2.
(1)建图
(2)
例题1 Courses(hdu1006)
(5)
(4)
例题1 Courses(hdu1006)
X学生
1
2 3
Y课程
1
2 3 1 2 3 1 2 3
1
2 3
1
2 3
(1)
1 2 1 2 1 2
(2)
1 2
(3)
3
3
3
3
(4)
(5)
#include<iostream> int link[303][303]; int used[303],mathy[303]; using namespace std; int P,N; int find(int x) {//x学生可以匹配到某课程 么 //可以返回1,不可以返回0 … } int MMG() { //计算最大匹配数, 调用了find … } int main( ) {int x,y,i,j; int cases; scanf("%d",&cases);
二分图的完备匹配

这个算法的要点是把初始匹配通过可增广轨逐次增 广,以至得到最大匹配。然后根据有无未盖点来判 定这个最大匹配是否为完备匹配。 例如求图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的每一个顶点盖住的匹配称为二分图的完备匹 配。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
应用3
男孩在一边,女孩在一边 会产生恋爱关系的连边 找最大独立集
应用4
一共N个人参加聚会,某些人之间会产生恋爱关 系(一定是异性之间)。现在希望找到最多的人, 他们之间不会产生恋爱关系。
应用4
所有的人复制成两份放在两边 会产生恋爱关系的连边 最大独立集 = N – 最大匹配 / 2
应用10
任务不分先后相同模式的连续做 用的模式越少越好最少的模式完成所有任务 把模式看成点,A的模式放在一侧,B的模式放在
一侧。 对于某个任务,在它所要求的两个模式之间连边。 最小点覆盖集
二分图最佳匹 配
最佳匹配:如果G为加权二分图,则权值和 最大的完备匹配称为最佳匹配。
KM算法
KM算法是通过给每个顶点一个标号(叫做 顶标)来把求最大权匹配的问题转化为求 完备匹配的问题的。
二分图的匹配和图论
二分图
一个图的点集可以划分为两个不相交的子 集,每一个子集中的点和该子集中的其他 点没有边相连
二分图
一个图是二分图的充要条件是这个图里没 有奇环
二分图匹配
匹配:给定一个二分图G,M为G边集的一 个子集,如果M满足当中的任意两条边都 不依附于同一个顶点,则称M是一个匹配。
应用7
路径覆盖:路径覆盖就是在图中找一些路径,使 之覆盖了图中的所有顶点,且任何一个顶点有且 只有一条路径与之关联 。注意一个单独的点也是 一条路径。
现要求有向无环图的最小路径覆盖,即在一张有 向无环图中,找路径数最少的路径覆盖。
应用7
把每个顶点拆成两份,然后按原图连边。
应用7
最小路径覆盖 = n – 最大匹配 每一个匹配相当于原图中的某两个路径合并
应用8
在一个有向无环图上,至少放多少个机器人可以 遍历整个图?
注意点是可以重复经过的。
应用8
允许重复经过点的最小路径覆盖 如果经过一个重复的点我们可以假装跳过了它进
入下一个点 Floyed求出传递闭包再做最小路径覆盖
应用9
在一个N*M的矩形里,有一些格子被毁坏。现在 要求用1*2的木板去覆盖没有被毁坏的格子,木 板不可覆盖彼此,问是否能把每个格子都盖住。
应用9
所有没有被毁坏的格子都看成图中的点 按格子的“奇偶性”分成两类 如果两个格子相邻,则在这两个点上连边 若存在完备匹配则所有的格子可以被覆盖
应用10
A机器有n个模式,B机器有m个模式。 现有k个任务需要做,可以用A机器的某个模式做 或者用B机器的某个模式做。 任务不分先后,但是机器换模式需要重启。现在 求最少的重启次数。
应用6
现在要求最多的小孩,两两之间不矛盾 从矛盾关系入手 猫和猫之间,狗和狗之间一定不存在矛盾关系 如果A小孩喜欢的动物与B小孩讨厌的动物一样,
或者A小孩讨厌的动物与B小孩喜欢的动物一样, 那AB之间就存在着排斥关系,则他们之间连接一 条边(他们不可能同时开心) 求最大的点集,两两之间没有边 最大点独立集
(删除原属于M的边,增加不属于M的 边) O(nm)
匈牙利算法
匈牙利算法
匈牙利算法
应用1
点覆盖集:图的顶点集的子集,覆盖图中 所有的边
最小点覆盖:无向图中,求最少需要多少 个点可以覆盖所有的边。 NP
应用1
二分图的最小点覆盖
应用1
König定理: 二分图的最小点覆盖 = 最大匹配
应用1
假设最小点覆盖=N,最大匹配=M 考虑最大匹配中的边两两不相交,所以至
少需要M条边覆盖。 得N>=M
应用2
独立集: 图的顶点集的子集,其中任意两点 不相邻。
最大点独立集: 无向图中,求一个最大的顶 点集,其中任意两点不相邻。
NP
应用2
覆盖集的补集一定是独立集 证明:
假设某一覆盖集的补集不是独立集。 说明有一条边连接了覆盖集的补集的两个 点。那么这条边没有被覆盖集所覆盖,产 生矛盾。
应用2
独立集的补集一定是覆盖集 证明:
假设某一独立集的补集不是覆盖集。 说明有一条边不被独立集的补集覆盖,那 么这条边连接了独立集的两个端点,产生 矛盾。
应用2
覆盖集与独立集互为补集 二分图中可求出最大匹配M 最小覆盖集=M,最大独立集=n-M
应用3
一共N个男孩和女孩参加聚会,某些男孩和女孩 之间会产生恋爱关系。现在希望找到最多的孩子, 他们之间不会产生恋爱关系。
应用6
动物园有N只猫,M只狗,P个小孩。每个小孩都 有自己喜欢的和讨厌的动物。如果他喜欢狗,那 么就讨厌猫;如果他讨厌猫,那么他就喜欢狗。 每个小孩会说,我喜欢__号猫,讨厌__号狗;或 者说,我喜欢__号狗,讨厌__号猫。如果他喜欢 的那只动物被留下,而且讨厌的那只动物被带走, 他就会开心。请问最多有多少小孩能开心。
M-饱和点:对于v∈V(G),如果v与M中 的某条边关联,则称v是M-饱和点,否则称 v是非M-饱和点。
M-可增广路:p是一条M-交错路,如果p 的起点和终点都是非M-饱和点,则称p为 M-可增广路。
匈牙利算法
匈牙利算法
For all i in X: 1、从i出发寻找可增广路 2、沿增广路更新
最大匹配:所有匹配中边数最多的。 完备匹配:如果一个匹配中,图中的每个
顶点都和图中某条边相关联,则称此匹配 为完备匹配。
二分图匹配
Hall定理
一个二分图有完备匹配的充要条件是: 任意k个点相邻的点的集合中不少于k个点
匈牙利算法
M-交错路:p是G的一条通路,如果p中的 边为属于M中的边与不属于M的边交替出现, 则称p是一条M-交错路。
设顶点Xi的顶标为A[i],Yi的顶标为B[i], 顶点Xi与Yj之间的边权为w[i,j]。在算法执 行过程中的任一时刻,要求对于任一条边 (i,j),A[i]+B[ j]>=w[i,j]始终成立。
应用5
给你一个N*N的格子,每个格子里要么有一个陨 石,要么为空。每一次你可以清除一行或者一列 里的所有陨石,求最少要多少次才能把所有的陨 石清除干净。
X
X
Xቤተ መጻሕፍቲ ባይዱ
X
应用5
把N*N的格子看成是一个二分图,每一行是一个 集合的点,每一列是另一个集合的点,那么某个 格子(x,y)中有陨石就相当于顶点x到顶点y有一 条边,那么要求使陨石全部被清理掉的最少的次 数,就是要使该二分图中的所有边都被覆盖的最 少顶点数。 X XX X