话说这题是一个搜索题。
我采用的是两次 DFS 的方法,也就是任意取一个点开始 DFS,找到这次 DFS 时深度最深的点(也就是从所选点开始最长路径的终点),然后从这一点(可以证明,这一点是最长路径的端点)开始再进行 DFS,这次 DFS 的深度就是要求的路径长度。
算法就是这样了,不过这个算法的正确性我一开始也不太确定,下面来证明一下:
大家看图:
设最长路径为 AB ,一开始任选的点为 P。取路径 PB 上的一点 Q,使得 AQ 与 PQ 只有一个公共点 Q(也就是使得从 A 走到 Q 再走到 B 不会走回头路)。设 AQ=a,QB=b,QP=s,不妨设 a<b。
要证明这个算法的正确性,也就是要证明从 P 开始的最长路径的终点一定是 A 或 B。假设从 P 开始的最长路径的终点是 C ,设 CP=c。
由假设知, c>s+b。由于从从 P 开始的最长路径的终点是 C,所以第二次 DFS 将从 C 开始,所得最长路径为 CB=c+s+b>s+b+s+b,又因为 a<b,故CB>s+b+s+b>s+a+s+b>a+b=AB,这与 AB 是最长路径矛盾,故假设不成立,命题得证。
时间复杂度 O(CR),空间复杂度 O(CR)。
代码还是非常 ugly,偷了很多懒,改一下的话应该能更快些。
P.S. 停止切题,准备期中考试。(其实这个星期就没做题)
Tags:algorithm,C++,OI,VijosRelated Posts

有
为常数
,于是这一区间内的数就可以只算一次,然后将结果乘以区间内整数的个数就行了。但当
时,每个区间的长度
,这样就得不偿失了,所以当
时每个区间处理一次,当
,有
,每个区间内,
为定值,所以令
,则对于区间
,有




。同样地,当
,空间复杂度 O(1)。