简要题解-图论-搜索-并查集-dp-树形-拓扑-tarjan等等

  • Post author:
  • Post category:其他



[USACO09NOV]找工就业Job Hunt

[图论,spfa,最长路]


attentions:对我而言非常好的一道题!最长路!

有几个点

1、这道题转化成最长路来求解,方法和最短路类似

2、但这道题是点有正权且只有负权边,且路径为单向!那么精妙之处在于,可以将点权转化为边权!!!

3、由于题目中可能出现正环(和最短路相反!),所以需要使用SPFA(判环和最短路类似)!


P2658 汽车拉力比赛

[并查集,二分搜索]

此题有两种方法:

1.二分搜索。结果一定为在海拔高度的区间内,而且结果是单调的,也就是说是有分界线的,而我们的目的就是找到这个分界线。所以用二分搜索不断进行判断。

2.建图、并查集。把所有点的差值作为边权,这样就建立起了一个图,然后给边排序,利用并查集找到第一个可以使所有路标联通的边,即为结果。


P3958 奶酪

【并查集,搜索】

两种方法:

1、搜索(DFS(更快)或BFS)

2、并查集(又是并查集!)。利用并查集找到图中所有可以联通的联通块,然后遍历记录的可达顶部和底部的点的联通块编号,判断他们是否属于同一个联通块。

两种遍历方法

1)一种O(n^2),直接两个循环

2)先排序,然后同时查询,复杂度为O(nlogn)

P1902 刺杀大使(

https://www.luogu.org/problemnew/show/P1902

) 【二分搜索】

二分搜索,只要有一条从第1层到第n层的通路即可。


P1576 最小花费

【乘法权值最短路】

最短路问题,不过边权的含义不同。是用乘法的。


P1828 香甜的黄油 Sweet Butter

【n次spfa,优化floyd】

最短路问题,但是居然要求n次!因为是稀疏图,所以用SPFA可以很快(O(km))。

据说优化的floyd也可以过,因为数据较小。


P1137 旅行计划

【dp,拓扑排序】

洛谷题解里面有好多用到先拓扑排序后dp的,可是这道题需要先拓扑排序吗?直接dp就好了吧,边权为1的DAG最长路?


P1550 [USACO08OCT]打井Watering Hole

【最小生成树,加点】

两种方法:

1、把建立每个源点的代价转化成一条和0结点相连的边,和那道“找工就业Job Hunt”有异曲同工之妙!!!

然后按照模板的Prim或Kruskal就OK了。

PS.和那道题的相同点是:而且边有权值,而且点也有权值。

2、Kruskal稍改版。看是把边连起来还是新建一个源点更省钱,不过不管哪个,都要合并并查集(因为在意义上他们是连通的)。

PS.似乎这又有启发?连通/生成树/并查集的另类含义?


P3916 图的遍历

【反向dfs,tarjan】

1、这道题可以用tarjan算法缩点,变成DAG,然后从出度为0的点开始遍历起,反向拓扑排序

2、但其实根本不用这么麻烦,只需要反向dfs即可,从编号最大的点开始遍历起直到遍历完所有的点。如果点权不是编号,那么需要进行一次排序。


P2835 刻录光盘

【tarjan,并查集】

1、可以用tarjan缩点,然后统计新的图的入度为0的点的个数

2、但其实这道题不用缩点那么麻烦,用并查集统计独立块的个数(即使是有向边),对每个独立块,如果有入度为0的点,那么这些点都需要ans++,如果没有入度为0的点,说明里面有联通块,ans++,而且那个联通块可以作为起点。

所以:虽然题目看上去是需要tarjan缩点的(转DAG模型),但我们只要探寻他的本质,我们只是要找起点而已,入度为0就是起点,如果一个块没有入度为0点,在缩点后的模型里,该点就是联通块。


P1038 神经网络

【拓扑排序,神经网络】

1、模型很简单,就是把神经网络模型转化为拓扑排序即可(本来就是)

2、但有需要注意:某节点值为负或0则不传递。


P1395 会议

【树形DP,图论】

非常不错的一道题,

这篇题解讲得非常好

暴力解法是dfs出每一个结点到其他结点的距离,但是这道题有特殊性:它是一棵树,且边权值都为1。这样的话就可以用dp来写啦,因为一个结点的结果可以从它的父亲结点那里推过来!以任一结点为根,dfs出它的值,以及每个结点作为子树根的结点个数(包括它自己),那么自己和父节点的边就可以作为分界了, 依据这个状态转移方程


d[x]=d[y]+(n-size[x])-size[x]=d[y]+n-2*size[x]d[x]=d[y]+(n−size[x])−size[x]=d[y]+n−2∗size[x]


P1271 聚会的快乐

【树形DP,记忆化搜索,字符串】

这道题是树形dp题目(二维),我们考虑当一个点被选入时,它的子结点都不能被选入,而如果它没有被选入,那么它的子结点可以选可以不选(看哪个幽默值更大),因此状态转移方程就是


dp[i][0] = sum(max(dp[j][0], dp[j][1])) {j: 0->edge[i].size()}



dp[i][1] = sum(dp[j][0]) {j: 0->edge[i].size()} + val[i]

但是实现的方法有两种:

一种自底向上,以拓扑序的顺序去进行dp,因为要得到一个点的dp值,只要得到其子结点的dp值

第二种是自顶向下,用dfs+记忆话搜索

因为题目给出的是这些人的名字,而不是结点编号,所以需要进行字符串转化,但是,题目数据似乎有重名的人,那么如果出现有歧义的描述怎么办?比如

2
Bob 1 Tim
Bob 2 Bob


P1922 女仆咖啡厅桌游吧

【树形dp,树形结构】

题目思路是尽量使得结点占满女仆咖啡厅和桌游吧,且他们是成对的,那么对于一个结点,它可以建立的建筑物是偶数的空位,且是最大偶数,因为其他的都可以建筑。那么如何获取一个结点的信息呢?考虑两个数据,子树的空位,子树已建立女仆咖啡厅的数量(答案),对于叶子结点,它的子树空位只有1,女仆咖啡厅的数量为0,那么往上递推,对于一个结点,他可以新建的女仆咖啡厅数量为空位/2,如果空位为偶,那么往上留的空位为0,否则为1,那么自顶向下的dfs就很好写了。


P1661 扩散

【二分搜索,曼哈顿距离,并查集】


曼哈顿图形维基百科

这道题的扩散图形是一个旋转了45°的正方形(曼哈顿图形里面就有关于这个“正方形圆”的描述),那么两个图形的扩散距离其实就是曼哈顿距离。那么就可以根据这些数据建立一个最小生成树(并查集),能不能建立一条边就看我们二分的边的长度了,最后二分出来的答案就是最小时间了。

PS:由于是同时扩散,所以是曼哈顿距离和时间乘以2比较


P1928 外星密码

【模拟,分治,自里向外】

这道压缩字符串模拟题,有两种方法可以求解,但其实都是自里向外的思想,只是形式不同。

1、用函数递归,分治的思想,对于字符串解压时遇到的每一个左括号,找到它在右边对应的右括号

2、统计左括号位置,然后从最右边的左括号开始解压起。因为从右边起(它是最里)的解压不会影响到左边。解压后将原字符串替换即可。使用

string的erase(), insert()

即可,参数为下标范围,左闭右开。


P2690 接苹果

【dp,记忆化搜索】

哎呀,即使是普及-的dp题目,也会这么难,真是让人伤脑筋。

总之就是建立模型的时候,有两个维度,一个是时间i,另一个是转换了多少次j,已知j可以求出奶牛当前的位置。状态转移方程为:


dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]



if j%2 + 1 == down[i] then dp[i][j]++


注意每次预处理

dp[i][0]

理解这个状态转移方程要从实际含义出发,对于一个状态

dp[i][j]

它一定是从i-1层转移过来的,而i-1层的哪些状态可能转移?这个状态要么会到另一棵树上去(dp[i-1][j-1]),要么在原树上面等待(dp[i-1][j]),只有这两种状态。而我们可以理解,

if j%2 + 1 == down[i] then dp[i][j]++

只跟奶牛在哪棵树下(即j的值有关),所以它在这个状态上要得到最大值,就要选择那两种状态的最大值转移过来。


P1825 [USACO11OPEN]玉米田迷宫Corn Maze

【spfa,bfs】

此题几乎就是BFS模板题了,多了一个会传送的而已,还是非常好处理的,但是如果用SPFA来写呢?如何将这张图转化为适合SPFA的图?

首先分析可不可以转(数据范围),

300*300

,嗯,比较小,而且每个点只能和上下左右四个点连成一条边,那么用spfa没毛病了。也就是给每个点编号,然后上下左右建边(如果可以),对于传送装置的处理,应该和另一个传送点建边。


P2746 [USACO5.3]校园网Network of Schools

【tarjan,缩点】

比较简单的缩点模板题,有几个需要注意的地方:

1、tarjan缩点时,对出度入度的处理,很多情况只要统计一个点是否有出度/入度,所以用bool值就可以。

2、注意考虑单个点的情况,满分的关键。

3、缩点后,当出点和入点相同时,务必跳过。



版权声明:本文为wjh2622075127原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。