【PAT】PAT总结《图论、动态规划》

本文详细介绍了PAT中涉及的图论问题,包括欧拉回路、哈密顿圈、拓扑排序等,并探讨了如何判断图的性质。同时,文章提到了动态规划在PAT考试中的应用,虽然PAT甲级已不考核动态规划,但依然列举了一些经典题目供读者参考。文章还讨论了单源最短路径、多源最短路和关键路径等问题,提供了模板和解题思路。
摘要由CSDN通过智能技术生成

图论判别题

这类题一般是给出一个图和一组查询,让你判断这组查询(一般是点集)是否是某种图或者某种路径或者某种点集。
首先要考虑针对顶点判别还是针对边判别
其次是选择邻接向量还是布尔矩阵或者是带权矩阵,我们要根据题目给的点集范围以及判别过程中需要获取点的相关边还是直接获取点和点之间的连通性信息,来选择数据结构。如果需要获取点的相关边,那么使用邻接向量比较方便,如果需要点和点之间的连通信息,使用布尔向量比较方便。如果既需要判断连通性,又需要快速(给出两个点)查询边权,应该使用带权矩阵。如果不需要直接查询两个点之间的边,而图又比较稀疏,那么应该使用邻接向量。
对于判别,可以正向考虑也可以逆向考虑。正向考虑就是满足什么条件的情况下,它是某种概念(比如哈密顿圈)等等,根据这些条件去判别。逆向考虑就是它不满足什么条件时,会降低成什么概念(比如不是圈,那一定是非TS圈,不是简单圈,一定是TS圈,否则是TS简单圈)。从这两个角度去考虑。逆向考虑的时候,如果逻辑有疏漏,可能会导致错误。如果找不出bug,可以考虑换个考虑(正向换逆向,逆向换正向)。
常常要考虑的问题:

  • 图/路径是否存在环。
  • 路径是否走了重复的顶点。
  • 图是否是连通图。以及题给的概念和连通图之间的关系。(比如非连通图不可能存在欧拉回路和欧拉路径)
  • 当图是桩(即只有一个顶点)的时候,它属于哪一类。
  • 当路径/点集满足什么条件时,可以将它的概念限定在什么范围。(比如,当一个路径的顶点数少于图中的顶点数,那么它不可能是哈密顿圈)
  • 查询是否一定合法(比如给出的查询可能包含无效路径/无效顶点)
  • 是否会出现平行边(目前还没有这种题,但是是可能的)
  • 是否会出现自环(目前也没有出现过,但是是可能的)

对于圈(当然,首先要判断这条路径首位顶点相同,是一个圈),我们常常排除路径的第一个点或者最后一个点然后进行计数,这样计数的时候,所有的顶点都只出现一次,也就意味着,首尾顶点出现了两次。
二重遍历的时候,要考虑是有向图还是无向图,如果是无向图的话是一个组合问题,对于u->v和v->u是等价的,所以我们可以总假设v>u来判别u->v即可。如果是有向图,那么是一个排列问题,显然u->v和v->u不等价。
下面我写的代码有一点点小瑕疵,如果只是需要判断是否经过一个点,使用布尔数组即可,不需要使用整型数组计数。
判断连通性可以使用DFS也可以使用并查集。DFS:从任意一个顶点开始执行一轮DFS,如果还有未被访问的顶点说明不连通。并查集:遍历边将顶点合并,最终连通分量为1说明连通,否则不连通。

欧拉回路

如果一个无向图是连通的,且最多只有两个奇点(或者0个),则一定存在欧拉道路。如果有两个奇点,则必须从其中一个奇点出发,另一个奇点终止;如果奇点不存在,则可以从任意点出发,最终一定会回到该点(称为欧拉回路,欧拉回路是特殊的欧拉道路)。

A1122 Hamiltonian Cycle

A1122 Hamiltonian Cycle
哈密顿圈的判别

A1126 Eulerian Path

A1126 Eulerian Path
欧拉图的判别,记得判断连通性

A1142 Maximal Clique

A1142 Maximal Clique

A1150 Travelling Salesman Problem

A1150 Travelling Salesman Problem
中国邮递员问题

A1146 Topological Order

A1146 Topological Order
拓扑序列的判别

A1134 Vertex Cover

A1134 Vertex Cover
这道题要求的是一条边至少有一个顶点被覆盖。因为一个顶点可能有多条边与之相连,从顶点的角度来考虑比较复杂,那么显然应该对边考虑。

A1131 Subway Map

这道题应该最好使用BFS寻最短路,群里有人说什么Dijkstra,其实是Dijkstra写多了盲目使用,首先得明白这是一个无向无权图,所以使用BFS就可以了,当然写出来和Dijkstra确实很像。无奈有一个点没有过,所以就不贴代码和思路了。柳婼使用了DFS,在这道题里没问题,但是数据刁钻一点可能就爆了。传送门

单源最短路径

基本上就是使用Dijkstra算法,这类题都快写吐了,上手Dijkstra。下面给出常用的几个问题的规律:

  • 关于计数路径数量,将起点设置为road[source] = 1,对于放松的每个顶点v,road[v] = road[u](因为此时必须从u走到v,所以从起点到u的路径数就是从起点到v的路径数),对于找到经过u的等权路径到达v,road[v] += road[u](此时相当于走到v多了从u到v这一分支,那么多出来的路径数就是从起点到u的路径数)。
  • 关于第二个标量的处理,在第一个标量相等的情况下判断第二个标量是否更优,更优则更新路线(但是不需要放松)。
  • 关于点权的处理,题目常常会要求最短路径的同时点权和最大,这时候可以贪心处理,在找到等权路径的时候,判断w[u] + w[v]是否大于w[v],是则更新它。也有可能是除了路径的其他边权,那就是w[u] + e.w2(w2代表第二个标量)是否大于w[v]。总之只要这个量是可以贪心的,我们就可以在等权路径上更新它。目前只有一道题例外,就是A1018 Public Bike Management。
  • 如果需要遍历多条路径,那么可以将edgeTo改成向量数组,放松的时候清空向量,加入新的u,找到等权路径的时候,加入新的u。
  • 要注意优先队列的定义,这个我被坑了好几次。

模板

	// 初始化
	fill(distTo, distTo + N, INT_MAX);
    fill(timeTo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值