要理解思想而不是代码!!!
昨天晚上的比赛。重新读了B题。然后发现当时读错题意了(1、乘积号看成和号2、输出n行,以为是一行)。今天读完了之后突然发现好水。立马敲了一遍kmp搞过了。注意的是每个单词长度len需要用strlen计算然后存起来,用length会超时。中文题居然都读错。瞬间感觉自己是个傻子。(下次再犯就给自己来10巴掌)
网络流虽然总结了一些题型,但是越看越懵,还是先来看二分图把。。。
二分图:
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
简单的说,一个图被分成了两部分,相同的部分没有边,那这个图就是二分图,二分图是特殊的图。
最小点覆盖:最小的点集使得其相连的边能覆盖所有边。
König定理:最小点覆盖=最大匹配
证明很简单,在得到最大匹配之后,一条边必然只有两种情况,两点都是匹配点,只有一个是匹配点。又因为对于一条匹配边来说,其两点上不可能同时连有非匹配点(即第二种情况的边),那么只需要把匹配边上两点的其中一点(含有第二种情况的点)包含到点集里,其另一点就可以通过选择的这个点来覆盖了(因为匹配边之间都是独立的)。
输出方案:(暂时没看懂,先把大佬的理解粘过来)
只不过要输出方案,其他方法不好处理,那么可以用S T 数组记录访问到的点,那么求出最大匹配之后,再从X部的非匹配点出发进行匹配,此时不影响答案,但是过程中访问到的点是必须要选的,不然这个非匹配点无法覆盖,另外不用考虑访问过程中访问到Y部的非匹配点,因为这种情况根本不存在。然后对于Y部非匹配点同样不会从X部匹配点出发,所以这样找出X中没有访问过,Y中访问到的点即使答案。
最小边覆盖:最小的边集使得其覆盖所有的点。
最小边覆盖=总点数-最大匹配
一条匹配边能覆盖两个点,而其他边只能覆盖非匹配点,也就是一个点,那么匹配边的贡献就是1,所以用总点数-最大匹配数即可。
最大独立集:最大的点集使得没有边连接相邻的点。
最大独立集=最小边覆盖=总点数-最大匹配
原理和上一个类似。。由于独立集合覆盖集互补,且最大匹配可以解覆盖集,所以最大匹配可以解独立集。。。
最小路径覆盖:对于DAG,用最小的路径个数覆盖所有的点。(一种路径不相交,一种路径相交)
例:UVAlive3126 Taxi Cab Scheme(DAG的最小路径覆盖)
DAG的最小路径覆盖。将每个人看做一个结点,如果时间允许到达就连边,则问题转化为DAG上的最小路径覆盖问题,即找到最少的路径使得每个点位于一条路径上。
算法:将DAG中的每个结点u拆分成2个为u1,u2,如果DAG中有边uv则连边u1-v2。如果该二分图的最大匹配数为ans,则答案为n-ans。可以这样想:在一条路径中除尾结点外其他结点都有且仅有一个后缀结点,把一个匹配看作成功找到一个后缀结点,则匹配数最大化即为尾结点最小化,即为路径数最小化。(by hahalidaxin )
总结:
最大匹配数=最小覆盖数
DAG最小路径覆盖数=DAG顶点数-二分图最大匹配数
最小边覆盖 = 顶点数 - 最大匹配数 = 最大独立集(最小边覆盖可以看做最小路径覆盖在二分图上的特殊情况)