13号:
(1)最小度限制生成树:求这么一颗最小生成树,他的某一个规定节点v0的度不超过k
看答案已解决:先把相连v0的边全删了,然后求最小生成树,当然形成了m个子树森林。就表明v0至少需要添上m条边才能联通整个图。如果m>k显然不存在v0的度小于k的方案;
如果m<k,我们先把v0到那些子树的最小的边加上使整个图联通,我们就得到了v0有m个度的最小生成树,在此基础上算度m+1的最小生成树,一直到k。那现在已经度m的最小生成树,如何算m+1的那?。。我们需要枚举v0没用上的边,添上这条边后那,会出现环。我们就需要吧环中不连接v0的最大的边删了,把这条边加上那就变成了m+1的生成树了。枚举为没用过的边,找到替换后差值最小的边,替换上。就是m+1的最小生成树了。
(2)哈夫曼距离最小生成树:这个已经单独写了博客了。
(3)计蒜客腾讯的狼人杀(困难)最大权密度子图:
已解决。还在思考如何优化建图,和如何使一些点必被包含 update :已解决
(4)分数规划:求一个割使得割的权值和/割的数量值最小。
解决。注意是个割,不是最小割。但是我们根据分数规划,设g=(割的边和)/割的大小,可以把每一个边重新赋值为 val-g,g是搜索的参数。就转化为最小割问题
14号:
今天看了会黑书,思考了一下下面几题:
(1):设计一个算法,求出一个正权无向图中从s到t的所有路径中最大值和最小值相差最小的路径:
解决:这个。曾经做过一道苗条的树的题目,就是求所有生成树中最大值和最小值相差最小的生成树。所以这个问题就很显然了。安权值排序,然后枚举最小边,并查集维护点的联通即可。复杂度m*m
(2):上面问题的深化:降低复杂度的关键?
未解决。我们可以发现上面问题优化的关键就是如何可以任意撤销并查集的某一步。这个貌似解决不了。。
(3):求出一个正权无向图中从s到t的包含k条边的最短路径:
解决。一不小心看到了题解,,浪费了一道好题。。。。。。可以用类似于floyd算,,假设A为邻接矩阵,,那k条边就相当于算 A^k,不过转移的时候不管距离变大还是变小都必须要转移,
(4):修改floyd\dijkstra,使得可以求出前k短路:
未解决。按道理,我们每个点可以设为dist【i】【k】,dist[i]【k】表示s到i的第k短路的距离。然后转移的时候有点僵硬,,,
(5):求第k最短路的A*算法:
解决:看了题解才发现其实很简单,就是暴力暴力。只是把最有可能通过优先队列先搞出来。。
(6):树上2点之间的边权极值:虽然很久以前就知道怎么做,但是感觉写起来麻烦。。还是整理一下吧。1)有修改明显就是树链剖分了。2)无修改的的话,可以树上倍增,每个点f[i][j],维护的是,i这个节点上2^j这段区间的极值,类似于ST表查询。3)无修改n小的话可以直接预处理用矩阵存,枚举节点进行dfs,复杂度n*n
(7):路的最小公倍数:给出一个带权(<1000)无向图,对于v0到v1的任意一条简单路径p。定义s(p)是p路径上的边权的最大公约数。求v0到v1的所有路径的s(p)的最小公倍数
解决:可以枚举素数的几次幂x,然后只跑能整除x的边,看看v0和v1能不能联通;
15号:
(1)一张无向图。节点有权值,边的权值是其端点权值的亦或。。现在给你一些节点的权值。。。让你给其他节点赋值。。使得的边的权值和最大
解决:我们知道位运算的每一位有独立性,所以我们可以一位位考虑,那问题转化为:一张无向图。节点有权值0或1,边的权值是其端点权值的亦或。。现在给你一些节点的权值。。。让你给其他节点赋值。。使得的边的权值和最大。
就是把一张图的点分为2个集合,使他们割边的权值最小,很明显的最小割思路。然后对于已经给权值的那些点不能让他们进行分割,,所以我们可以将他们的边容量设为INF。所以就这样连边:对于已经给权值的点,若该位为1,就连一条无穷大的边向汇点。为0,源点连一条无穷大的边向该点,如果uv有边就连一条cap为1的双向边
(2)混合图的欧拉回路:
解决:先把边任意定向,然后根据平衡的条件,如果此时的in-out>0,那么需要有(in-out)/2的in边反向。我们从该点连一条cap为(in-out)/2的边向汇点。同理,in-out<0,我们从源点连一条cap为(in-out)/2的边向该点。
然后跑最大流,当附加边满载时,有解。然后把所以有流的边反向就为欧拉图
16号;
(1)图的次短路的条数:
解决:最短路的条数应该很熟练了,次短路的话,和最短路差不多。用dij的话,,开个两维记录最短和次短,更新的时候综合考虑下就好了