首页 > 代码库 > 蓝桥杯 历届试题 大臣的旅费 DFS两次
蓝桥杯 历届试题 大臣的旅费 DFS两次
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
输出一个整数,表示大臣J最多花费的路费是多少。
1 2 2
1 3 1
2 4 5
2 5 4
大臣J从城市4到城市5要花费135的路费。
题目就是这样,,但是我很崩溃啊。。在蓝桥官网的OJ上最后一组测试数据总是RE,,可是我看了两个小时的代码,就是没发现有什么BUG。我也上网搜其他人博客上的代码,,我发现最好的情况就是和我一样的状况(有的人的代码写的跟shit一样。我懒得复制)。。都是第四组测试数据RE,其他人的代码不是TLE,,就是每组测试数据都WA!!有的人真不负责任,错的代码贴到网上也不说声代码有问题。
下面来说说这道题的思路,大部分对这道题的第一印象就是Floyd算法(虽然在两个小时前我还不懂什么是Floyd算法,但是思想是一样的),,O(n^3)的复杂度,这样的复杂度,一般就是超时的命了。。所以我果断抛弃了。接下来搜到一个人的博客,他的代码经过测试也是错的(o(╯□╰)o),但是他的思路是正确的,他的博客地址我就不贴了,反正代码不对,我把他的思路说一下,
首先从u dfs找到最远点v ,然后从v开始,dfs找到的最远点一定是树的直径
证明:
如果u->v 和树的直径没有公共点,则可以从树的直径终点到u引一条边,树直径变长了,矛盾
假设交点为k,那么k->v (或者就是v本身) 一定是树直径的一部分,(最优子结构)
这样就证明了v一定在树的直径的端点处,(为什么是端点,因为u->v是最远的,一定是叶子节点)
我就是照着他的思路来的,算了,我还是贴上他博客的地址吧。http://blog.csdn.net/jingqi814/article/details/21825865
下面是我的代码:
#include <stdio.h> #include <string.h> #define MAX 7010 #define INF -22222222 int t[MAX][MAX]; bool flag[MAX] ; int dis=INF , v ; int DFS(int sum , int pos , int n) { if(sum>dis) { dis = sum ; v = pos; } flag[pos] = true ; for(int i = 1 ; i <= n ; ++i) { if(t[pos][i] != 0 && !flag[i]) { DFS(sum+t[pos][i],i,n); } } } int main() { int n; scanf("%d",&n) ; for(int i = 0 ; i < n-1 ; i++) { int u , v , w ; scanf("%d%d%d",&u,&v,&w); t[u][v] = t[v][u] = w ; } DFS(0,1,n) ; dis = INF ; memset(flag,0,sizeof(flag)) ; DFS(0,v,n) ; printf("%d\n",dis*10+(1+dis)*dis/2) ; return 0 ; }
这是评判情况:
我真的不知道哪里错了。。好崩溃
虽然我的代码有一组数据没通过,,但还是有一定价值的,,如果有看到BUG的同学,,希望跟我说声,,万分感谢!!!!
蓝桥杯 历届试题 大臣的旅费 DFS两次