问题描述 很久以前,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 5 1 2 2 1 3 1 2 4 5 2 5 4 样例输出1 135 输出格式 大臣J从城市4到城市5要花费135的路费。
记:
第一次写的时候,是从每个结点遍历,从而找到最长路径
然而在测试较大数据时会超时,
在参考过http://blog.csdn.net/rodestillfaraway/article/details/50529769
醒悟到,可以先找到最远点,再从最远点开始遍历寻找最长路径,就可以避免搜索多余的短路径(剪枝)
ps:
关于邻接表的使用,可以参考之前写过的
http://www.cnblogs.com/mind000761/p/8467789.html
示例代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define LEN 10000 4 5 typedef struct node node_t; 6 typedef struct node 7 { 8 int n; /*下一个结点*/ 9 int v; /*边权值*/ 10 node_t *next; 11 }node; 12 typedef node *node_p; 13 14 int n = 0; /*结点*/ 15 int max = 0; /*最长路径*/ 16 int vis[LEN]; /*访问标记*/ 17 node_p e[LEN]; /*邻接表*/ 18 19 void add_edge(int x,int y,int v) 20 { 21 node *p; 22 p = (node *)malloc(sizeof(node)); 23 p->n = y; 24 p->v = v; 25 p->next = e[x]; 26 e[x] = p; 27 return ; 28 } 29 30 void init() 31 { 32 int i; 33 int x,y,v; 34 scanf("%d",&n); 35 //e = (node_p *)malloc(sizeof(node_p)*(n+1)); 36 //vis = (int *)malloc(sizeof(int)*(n+1)); 37 for (i = 0 ; i <= n ; i ++) 38 { 39 e[i] = NULL; 40 } 41 for (i = 1 ; i < n ; i ++) 42 { 43 scanf("%d %d %d",&x,&y,&v); 44 add_edge(x,y,v);/*无向图,需添加两条边(双向)*/ 45 add_edge(y,x,v); 46 } 47 return ; 48 } 49 50 void dfs(int x,int len) 51 { 52 node *p = e[x]; 53 while (p != NULL) 54 { 55 if (!vis[p->n]) 56 { 57 vis[p->n] = 1; 58 dfs(p->n,len+p->v); 59 vis[p->n] = 0; 60 } 61 p = p->next; 62 } 63 64 if (len > max) 65 { 66 max = len; 67 n = x; 68 } 69 70 return ; 71 } 72 73 int main(void) 74 { 75 int i; 76 init(); 77 78 /*第一次找最远端的点*/ 79 vis[1] = 1; 80 dfs(1,0); 81 vis[1] = 0; 82 /*第二次由于是从最远端开始找,可以确保为最长路径*/ 83 max = 0; 84 vis[n] = 1; 85 dfs(n,0); 86 87 n = 10*max; 88 if (max == 1) 89 { 90 n ++; 91 } 92 else if (max%2) 93 { 94 n += (max/2 + 1)*max;/*奇数*/ 95 } 96 else 97 { 98 n += (max/2)*(max+1);/*偶数*/ 99 } 100 101 printf("%d",n); 102 return 0; 103 }