摘要:
题意:对于一个长度为2^N的循环序列,从某一个位置开始依次取N个,这样就能够生成2^N个序列,现在要求输出一个最小的满足要求的循环序列。输出这个序列生成的第K个数字是多少?解法:套用Fleury算法,构边的时候保持从小到大的顺序即可。如果是生成N为序列的话,就考虑前N-1位构成的节点相互的连的边(例如三位数就可以这样构边 00 --> 01 --> 11那么这两条边就代表生成了001和011这两个数字),输出欧拉回路即可。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#incl 阅读全文
摘要:
上面是摘自图论书上的定义。算法在运行过程中删除了所有已走的路径,也就是说途中残留了所有没有行走的边。根据割边的定义,如果在搜索过程中遇到割边意味着当前的搜索路径需要改进,即提前输出某一个联通子集的访问序列,这样就能够保证访问完其中联通子图中后再通过割边访问后一个联通子图,最后再沿原路输出一开始到达该点的路径。如果只有割边可以扩展的话,只需要考虑先输出割边的另一部分联通子集访问序列。样例图:代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#in 阅读全文
摘要:
题意:给定一个进行了集合划分的序列,现有一套标准答案,同样给定了M个非标准答案,现在要计算这M个非标准答案的最大正确率为多少?解法:该题考虑的是可以采用不同的字符进行相同的划分。那么求解的就是一个集合符号的匹配的问题,采用何种的集合符号一一对应才能使得正确率最高。那么对于每对应某个位置的集合标号,我们可以假设是对应的,那么在这个基础上再进行更多的匹配,建立起x字符对应y字符最多能够对多少个的一个边,然后调用KM算法即可。在读取数据的时候使用gechar死活过不了(会读到非字母导致RE,可能是数据中有多个空格或者...),还好有cin这个利器,不过就是速度慢了点。代码如下:#include &l 阅读全文
摘要:
题意:给定一系列的匹配关系,现在有些匹配时不允许的,问最大匹配时多少。解法:解决问题的办法就是在计算松弛d值的时候,如果d的值在经过一次可行标的更新后仍然不能得到某个最小值来扩充原图的边集。那么就不存在一个最优权值匹配。注意当值为负的时候就不能够匹配。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f; 阅读全文
摘要:
题意:这题自己YY了下,没想到结论还是对的。题目告诉我们一个有向图,现在问将图中的每一个点都划分到一个环中的最少代价是多少?每条边都有一个代价。解法:由于要成环,那么将这个图进行拆点,就变成了单向的二分图了,此时一个完备匹配就是一种连线策略,只要保证没有边是和自己相连,就能够满足题目中要求的每个点至少属于一个环。证明也是很简单的。因为我们总可以从一个完备匹配中找出起点,然后再从匹配点作为起点找......左图可以看做是1,2成环,3,4,5成环。代码如下:#include <cstdlib>#include <cstring>#include <cstdio> 阅读全文
摘要:
题意:给定一个二分图,N个点对应M个点,两两之间存在一组关系,每组关系一个权值。题目中了给定了一个匹配方案,现在要求满足这组关系中的最大的匹配权值在原方案上增长了多少?并且还要求求出在原匹配方案上改变最少多少条边能够得到这个最大匹配?解法:该题求增加了多少匹配值非常好算,问题就是这个最少改变多少条边。前面做过一道题目使用dfs遍历出所有的最优匹配情况,果断用在这里超时,主要原因是点过多,当然还有就是最大匹配不太好剪枝。想了许久硬了没有法子。百度......正确的解法真他妈犀利,主要思想就是增加原配边的权值,而且又不会对结果造成影响。这听起来似乎是不太可能的,但是确实有办法能够办到。首先由于顶点 阅读全文
摘要:
题意:此乃第一道真正意义上的最大权值匹配,其他题目其实都是求一个最小权值匹配。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;int N;int w[305][305];int lx[305], ly[305];int sx[305], sy[305];int match[305], slack[3 阅读全文
摘要:
题意:给定平面上两类同样多的点,要求输出一种方案使得所有匹配的点的连线两两不相交。解法:考虑到下面的一般情况:可以很容易的证明两条交叉边的距离和一定大于两条不交叉的距离和,因此问题转化为只要原图中存在交叉边,那么就可以找到更小的匹配的方式使得总距离更小。使用KM算法求出最小权值匹配输出匹配方案即可。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>#include <iostream>#include <cmath>u 阅读全文
摘要:
题意:给定N个限定了边长范围的正方形,现在要把它们全部铺到长度固定,高度不限的墙上,一共有N种颜色一一对应使用,告诉每种颜色的单位面积价格。问铺满墙的最少开销是多少?只要长度为L的墙被覆盖了所有长度即可。解法:该题有个良好的性质为不论给定的正方形的顺序如何,都不影响最后的结果。设状态f[i][j][k]表示放置到第i个覆盖长度为j,且颜色选择为k时的最少开销。其中k是状态压缩的选择方案。那么有动态规划方程f[i][j][k] = min(f[i][j][k], f[i-1][j-p][k']) 其中p为第i个正方形合法的取值边长,k'为选择了i-1种颜色的方案,也是是k‘中有i 阅读全文
摘要:
题意:给定一个字符串,按照要求输出来。解法:每次进行一次首字母判定,然后根据不同的情况进行递归。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <algorithm>using namespace std;char str[300];string display(int ti, int sta, int fuck) { string ret; if (sta > 阅读全文