12.15 省选训练总结4 图论算法

来源:互联网 发布:vcm仿真实验软件 编辑:程序博客网 时间:2024/06/05 11:44

目录

完成情况 题目 出处 GGS-DDU HDU 4966 Journey CDOJ 92 Network POJ 1144 朋友圈 BZOJ 2744 [HEOI 2012] 放箱子 CDOJ 1432 Harry Potter and the Forbidden Forest HDU 3987 度度熊的交易计划 HDU 6118 Kejin Game UVALive 7264 Teamwork HDU 4494 Less Time, More profit HDU 5855 网络流五 Hihocoder 1398 Going Home POJ 2195 Sofa, So Good Codeforces Gym 100642H zsy与wj的连边之战 FLOJ 906

最小树形图

最小树形图相当于无向图的生成树,是选定一个根以后以最小边权和构造一棵有向树,这棵有向树的边总是从父亲指向儿子的。

算法是朱刘算法:

  1. 对所有除了根以外的点找一个权值最小的、指向他的边。假设这个边权是prei
  2. 这些边肯定构成了:要么一棵树,要么一片基环森林,也就是有一些环和一些指出环的边。先把当前答案加上去。如果这是一棵树,那么算法就到此为止了。如果这有一些环,就尝试缩环重做。
  3. 缩环以后怎么建边?首先是指出的边,这些边的加入一定不会使得环的内部结构改变,所以指出边仍然是原有边权。其次是指入的边,这些边一加进去,就必须断开环里的原有父亲(因为在重做的时候环里的边没法直接去掉,必须找一个替代),断开以后原有边就必须删去。这个时候相当于建边的边权是原有的边权减去prei
  4. 缩环建边完了以后回步骤1。

还有一些值得注意的问题和算法的理解:

  1. 最小树形图最终有多少条边?从其定义方面来看,有n1条。从另一方面,算法过程来看,由于每个非根点只存在一个pre,并且在环中,已经有pre的点要找新的pre就相当于必须断掉原有的pre,所以还是只有n1条,从另一方面印证了算法正确性。
  2. 缩点?我们知道一个点也可以看作一个极端的环缩成它本身,所以每个点也可以用环的方式去理解。在这个环中点没有任何pre,所以pre=0,从环的角度考虑也没问题。
  3. 复杂度?每一次扫所有点的pre的复杂度是O(m)的,但是最极端的情况下算法最多进行n次就会成为一个点,或者不足n次就退出,所以复杂度是O(mn)

GGS-DDU

总共有n门课,每门课有一个最高等级ai,一开始每门都是等级0

m个提升班,每个班级有al1bl2w,表示只有第a门课程在l1及以上时才能上,花费代价w,可以将第b门课程提升到l2等级。

现在问将所有的课程提升到最高等级需要付出的最小代价,若无法达到则输出1

因为涉及了每个科目有等级,所以考虑拆点建图。拆点的时候千万不要直接按照ai去拆,因为可以看到题中最多涉及2m个等级,所以离散拆点。

然后发现这个是要求所有提高到最高级,相当于到达所有点,所以考虑如何用最小树形图做。

首先建边的时候最先想到的应该是同一门课进了高级别就应该相当于自动进了低级别,只需要高级顺次向低级连0边即可。

然后提升班,就直接按要求连边。

总复杂度O(m2)

LCA

LCA的tarjan,RMQ,倍增算法已经熟练掌握,这里就不再多讲。

Journey

给你一棵树,然后在树中加入了一条边。

然后q次询问,问你加入了这条边之后询问的两个点距离变短了多少。

先考虑加边之前:可以直接裸的LCA做。

考虑加边之后:只需分别找到到加的边的两个端点的距离,加上边权就是答案。

Tarjan缩点

首先Tarjan缩点的板我在NOIP之前已经练的不能再熟了。dfn和low记时间戳和最小访问时间。

然后是割点和桥,这两个放到dfs树上想比较好。

桥的条件是这条边以下的点不能返祖到这条边上面。

割点的条件是这个点以下的点不能返祖到这个点上面(不含这个点),对于根的条件是儿子数大于1

Network

求割点裸题。

次短路

第一种就是在更新的时候同时记录在这个点的最短和次短,最短只能由最短更新,但次短既可能由最短更新,又有可能由次短更新,有点类似于dp

第二种就是记录每个点到起点和终点的最短距离,然后枚举每一条中间边,查看到两端的距离。

春天来了

这里有n个男孩和n个女孩要组成n对好朋友。

每个人都有一个腼腆值,每当一个男孩和一个女孩成为好朋友,产生的尴尬值就是他们腼腆值的乘积。

为了都能找到好朋友,我们现在要帮助他们进行男女配对,目标是让他们所产生的尴尬值总和最小。

看起来是一个二分图匹配,但是边数一共有n2条过不动。仔细一看排序贪心即可。

网络流

算法我已经理解得比较好,模板很熟。

当前弧优化后面再提。

二分图的基本建模

最小路径覆盖:把每个点拆成两个点,一个点终点向另一个点起点连边跑二分图。

二分图的最大覆盖集=最大匹配数,因为如果有边不被覆盖,就可以加入匹配。

二分图的最大独立集=点数-最大覆盖集,因为它们互相没有关联。

朋友圈

A国:每个人都有一个友善值,当两个A国人的友善值ab,如果axorbmod2=1,那么这两个人都是朋友,否则不是;
B国:每个人都有一个友善值,当两个B国人的友善值ab,如果axorbmod2=0, 或者 aorb化成二进制有奇数个1,那么两个人是朋友,否则不是朋友;
A、B两国之间的人也有可能是朋友,数据中将会给出A、B之间“朋友”的情况。

求最大团。

(另可见FLOJ 824)

首先A国只能选一奇一偶,然后枚举这两个A国人,找出符合条件的B国人分成奇偶跑补图的二分图匹配的独立集,匹配了的就是不能同时出现的,独立集大小就是答案。

放箱子

给出一个nm的矩形仓库,仓库里有的位置已经被占用,问这个仓库还可以放下多少个12或者21的箱子。

棋盘二染色,由于一个箱子只会占据相邻的一个黑格一个白格,他们之间连边,跑二分图即可。

Harry Potter and the Forbidden Forest

求割边数最小的最小割。

我在青岛区域赛做过。

对于这类多关键字排序的题有一类通法,就是把两者合并起来并且把相互之间的干扰去掉,有点类似于反基数排序。

消除干扰只需要把首要关键字乘上一个固定的较大值,使得次要关键字不会对其造成影响即可。

在这题建边是c(m1)+1

度度熊的交易计划

地区一共有n个片区,m条公路组成。第i个片区能够花费ai元生产1个商品,但是最多生产bi个。第i个片区也能够以ci的价格出售最多di个物品。每一个商品运输1公里,将会花费1元。求最大收益。

这费用流按题意建图即可。源向片区连(bi,ai),片区向汇连(di,ci),运输的话在片区之间连(inf,1)即可。

Kejin Game

你现在在点一棵技能图,你想学会一个技能有三种方式
1,学会它所有的父技能,然后花费ai的代价学会它。
2,花费bi的代价,可以不学某个父技能。
3,花费ci的代价,直接氪掉这个技能。
现在问你,最少花多少钱,能学到某个技能。

这是经典的代价问题,涉及代价合并和取优。

首先考虑氪掉,这个点拆成两个点连ci可以直接断开。

然后考虑不氪它,就必须自己学要花ai,从源点连过来。

最后是父节点不学,就相当于不需要考虑父节点部分就可以把前面断开,是从父节点那里连过来bi

Teamwork

给你一些任务,每个任务有固定的开始时间和需要多久能干完。
每个任务都需要一些人,这些人有最多五个种类,各种类之间的人不能相互替换,但是某些工人干完这个活后如果可以在另一个任务还没开始的时候赶过去,也可以帮那个任务干活,干的是自己的属性的活。
所有的任务必须人齐了才能干。
最少要多少个人能把活干完。

先把每种工人分开来单独考虑,因为他们互不影响。每个点拆成两个点,一个用于自己消耗,一个用于给予他人。

每个消耗点先向汇点给一条边表示要完成这个任务的人数,帮助跑满流。费用0

然后每个消耗点从源点连一条人数边费用1的边,这是真正从源点拿来的人。

然后每个人工作完以后产品流出去,人却可以继续工作,所以给予点会给出和该任务人数等量的人出去。这些相当于免费拿来了等量新人,从源点连费用0边。这些人可以发配到别的任务消耗点上消耗掉,连费用0无上限边。

最大权闭合子图

闭合子图:任意一点V在子图内时,其出边E在子图内。任意一边E在子图内时,其端点UV在子图内。

最大权闭合子图出现在求一些正负点中选出一个集合的问题。

做法:最小割,割掉与S相关的边表示不选,割掉与T相关的边表示被选。
如果没有被割完,出现形如SABT的增广路,意义就是A被选,B不选,但条件要求A选时B必须选。

正权点向源点连流量为权值的边,负权点向汇点连流量为权值绝对值的边。跑出最小割后用总的正边权减去最小割。

Less Time, More profit

M个商店,N个工厂,每个商店获利的条件是建设了指定的k个工厂。求总获利不小于L,工厂建设的时间最大值最小是多少。

首先二分这个时间,然后建图求获利。建工厂是负权,商店是正权,商店的边指向工厂,做最大权闭合子图。

[hihocoder]网络流五

一共列出了N项不同的活动,第i项活动能够产生ai的活跃值。
班级一共有M名学生,邀请编号为i的同学来参加活动需要消耗bi的活跃值。
每项活动都需要某些学生在场才能够进行,若其中有任意一个学生没有被邀请,这项活动就没有办法进行。
求最大活跃值。

和上题一样,搞活动是正值,请学生是负值,搞活动向请学生连了边,做最大权闭合子图。

带权二分图匹配

KM?可以用费用流替代,复杂度同级。

Going Home

给定一个NM的地图,地图上有若干个man和house,且man与house的数量一致。man每移动一格需花费$1,一间house只能入住一个man。现在要求所有的man都入住house,求最小费用。

每个man和house之间的连边的费用是曼哈顿距离,建好图做带权二分图即可。

Sofa, So Good

工厂里生产沙发需要经过两个步骤,现在n个人生产n个沙发,每个人负责一个沙发的第一步骤和一个沙发的第二步骤。每个沙发必须先经过第一步骤的加工再来到第二步骤。
需要满足以下条件:
1,第一步运行时间短
2,第二步运行时间短
3,摸鱼(空闲)时间短

这个题面是在吓唬人,第一条满足的时候是有唯一匹配的, 所以分步一步一步做费用流即可。第三条在满足一二条的时候自然满足。

zsy与wj的连边之战

你可以从网格图右侧向左侧进攻,不可以跳过右侧的而进攻左侧的,并且有一些格子在未被消灭的时候可以保护另一些格子。每个格子有正负权,求最大权。

这个题首先它有环,而且可以发现有环不仅不能取,而且连被环上的点保护的格子都不能取。先做dfs标个标记。
接下来剩下的就是最大权闭合子图,左向右连边,被保护的向保护者连边。

总结

网络流的基本建模构架方式有拆点和建超级源汇两种。
看到DAG选取正负权可以考虑最大权闭合子图。
看到工人做东西可以考虑费用流。