0.引子
题意:给出若干大小为偶数的数组,对于每个数组,将一半的数放入集合A,另一半放入集合B。问是否有一种分法,使得A=B。
解0.5:嗯将所有东西分为两堆,很容易想到二分图。现在来建图,考虑将所有数分为一边,两个集合分为另一边,但是要怎么保证每组分出去一半数。。。那再加一排组,这有点像网络流,问题不大反正二分图能拿网络流跑,所以最终流量是什么呢。。。算了先复习一下二分图吧。
1.概念
二分图判定:图中不存在奇环。
代码待添加
二分图最大匹配:选出最多的边,使得没有两条边共用一个顶点;
二分图最小点覆盖:选出最少的点,使得每条边都有一个端点被覆盖。
著名定理:二分图最大匹配=二分图最小点覆盖。
二分图最小路径覆盖:选出最少的边,覆盖所有的点。
著名定理:二分图最小路径覆盖=所有点个数-最大匹配。
最大匹配算法:匈牙利算法

int n,m; int vis[maxx]={0},match[maxx]={0}; int dfs(int now){ for(int i=0;i<e[now].size();i++){ int to=e[now][i]; if(!vis[to]){ vis[to]=1; if(!match[to]||dfs(match[to])){ match[to]=now; return 1; } } } return 0; } signed main() { ... int ans = 0; for (int i = 1; i <= n; i++) { memset(vis, 0, sizeof vis); if (dfs(i)) ans++; } ... }
二分图匹配的模型有两个要素:
1.节点能分成两个独立的集合,每个集合内部有0条边;
2.每个节点只能与一条匹配边相连。
我们把它简称为“0要素”和“1要素”。在把实际问题抽象成二分图匹配时,我们就要寻找题目中具有这种“0”和“1”性质的对象。
——《算法竞赛进阶指南》
好书,好书。
好书配了点例题,还有之前做的两个题,现在往里套一套。
2.例题
1.POJ-3041
题意:给定一张n*n的图和k个点,每次可以消灭一行和一列的点,求最少几次可以把所有点消灭完。
解:每个点要么被所在行消灭,要么被所在列消灭,这两件事中只能发生一种,是1元素。行和列显然没有联系,是0元素。那么行和列为点,k个点作为边元素,将所在行和列连接起来。现在来看这张图,意思就是:选取最少的点,覆盖所有的边,为最小点覆盖、
2.POJ-3020
题意:给定一张图,上面有很多*。有一些1×2的小纸片,问至少用多少小纸片能覆盖所有的*。
解:小纸片一次能覆盖两个格子,若把棋盘分为黑白相间的格子,那也就是说,颜色相同的两个格子之间不能有小纸片。虽然听起来很怪,但棋盘上的0要素经常这么搞。然后看 * ,每个 * 只能被一个纸片覆盖(当然也可以盖两个,但没有必要,除非要盖另一个点时盖到了它,可这个纸片不能算它头上)。现在将黑白格分为两列,上面有星星的可以向四周连边,要求选取最少的边,覆盖所有有星星的点。既然要覆盖的是有星星的点,那其他点可以忽略,然后求最小路径覆盖。注意现在连边是双向边,最后最大匹配个数要/2。至于有的点没有连边也没关系,画个图会发现算进去了。
3.棋盘覆盖
题意:棋盘上有一些禁区,问在1×2的骨牌不重叠的情况下,最多能放多少骨牌。
解:同样将黑白两色格子分开,每个格子最多只能被覆盖一次,也就是选取最多的边,边与边之间没有共同点,二分图最大匹配。
*4.POJ-3565
虽然和上面的画风不太一样,但挺好玩的。
题意:给出n个白点和n个黑点的坐标,要求一 一配对,总路程最小且任意两条线不相交。
解:任意两条线不相交其实就是路程最小的意思,跑最大权匹配就可以了。
5.POJ-1325
题意:AB两台机器都有M种模式。每个任务在机器A上执行,需要调为a[i]模式;在机器B上执行,需要调为b[i]模式。任务可以以任意顺序执行。每次换模式需要重启,求重启最小次数。
解:每个任务要么在A上执行,要么在B上执行。A和B不能同时出现。A和B的M个模式为两排点,任务执行为边,连接两种模式。要求选择最少的点,覆盖所有边。最小点覆盖。
3.最大独立集
其实没有必要单独拎出来,但书看到这里是个新概念。
1.概念
图的最大独立集:点集中任意两点之间没有边。
图的最大团:点集中任意两点有边。
*对于一般无向图,最大独立集和最大团属于NPC问题(太好了我最喜欢NPC问题了这样就不用做了(毫无探索精神的咸鱼
定理:对于二分图,最大独立集=n-最大匹配数。
二分图最大独立集=二分图最小路径覆盖。
*对于有向无环图,最小路径覆盖=拆点后二分图的最大匹配。
2.例题
题意:骑士们按“日”字攻击,问棋盘上最多放多少个不能互相攻击的骑士。
解:日字两对角不能同时放人,连边。但是有点不一样,上面的棋盘覆盖是两个点不能被同时覆盖,但都要覆盖,这是有你没我。要求选取最多的点,且每两个点之间不能有边。最大独立集出来了。
4.尾
对于0元素和1元素的乱解读:0元素即不能同时出现的两方,通常被分为两边节点。1不一定是仅限一次,主要代表有这个事件的发生。这样粗略连出图后,即可根据题意判断要求什么。
好我们接下来看开头的题目。每个数要么在左边,要么在右边,但怎么分正是要求的东西,不能用它来分结点,得找另一个要么……要么……。离谱的想法出现了,一个数只在一个组里,但这组未免太多了一些。
题解,打开!
解1.0:将数组和数分为两边,数在数组里则连边,出现几次连几条边,然后找这张图的欧拉路(……),从右往左为一组,从左往右为另一组。从边看,每个数都分到了一组,并且由于度是偶数,还平分了。
完全没有用呢阿sir,去看女子1000米决赛辽!
——比赛很快结束了,有人欢欣鼓舞,有人抱头痛哭,竞技大抵都是如此吧。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?