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

[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、缩点后,当出点和入点相同时,务必跳过。

你可能感兴趣的:(图论,搜索,DP)