问题 1438: [蓝桥杯][2013年第四届真题]大臣的旅费

问题 1438: [蓝桥杯][2013年第四届真题]大臣的旅费

时间限制: 1Sec 内存限制: 128MB 提交: 547 解决: 127

题目描述

很久以前,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最多花费的路费是多少。 

样例输入

5 
1  2  2 
1  3  1 
2  4  5 
2  5  4 

样例输出

135

分析:该题目题意就是要求树的直径。
求树直径原理:以任意点w开始,先做一次DFS(BFS),找到最远点v,然后以此点v,进行一次DFS(BFS),找到最远点u,u到v就是树的直径,记做d(u,v)。

证明:

1) 如果w 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点x使得w到x的距离更长,则与d(u,v)为直径冲突)

2)如果w不是直径上的点,则w到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了,所以v一定是直径的一个端点,所以从v进行DFS得到的一定是直径长度

#include<iostream>
#include<algorithm> 
using namespace std;
struct EDGE{
	   int v,w,next;
}head[100009];
int    u,ans,h[100009] ,cnt=0,vis[100009];
void   add( int u ,int v ,int w ){
	   head[cnt].next = h[u];
	   head[cnt].v = v;
	   head[cnt].w = w;
	   h[u] = cnt++; 
}
void   dfs( int vv ,int val ){
       if( val > ans ){
       	   ans = val;
       	   u   = vv; 
	   }
	   vis[vv] =1; 
       for( int uu = h[vv] ;uu!=-1 ;uu=head[uu].next ){
	   	    if( !vis[ head[uu].v ]  ){ 
		  	     vis[ head[uu].v ]=1;
			     dfs( head[uu].v ,val+head[uu].w);
	        }
	   }  
}
int    main(void){
       int n,a,b,c;
	   cin>>n;
	   fill(h,h+n+1,-1);  
	   for( int i=1;i<n;i++){
	   	    cin>>a>>b>>c;
	   	    add(a,b,c);
	   	    add(b,a,c);
	   }
	   ans=-1; 
	   dfs( 1 ,0) ;
       ans=-1;
	   fill(vis,vis+n+1,0);
	   dfs( u ,0) ;
	   cout<<( ans * 10 + (1 + ans) * ans / 2 )<<endl;
	   return 0;
} 
发布了761 篇原创文章 · 获赞 134 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/S_999999/article/details/104088191