Description
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
Input
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
Output
输出一个整数,表示大臣J最多花费的路费是多少。
Sample Input
5 1 2 2 1 3 1 2 4 5 2 5 4
Sample Output
135
HINT
输出格式
大臣J从城市4到城市5要花费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得到的一定是直径长度
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <queue> 9 #include <set> 10 #include <stack> 11 #include <map> 12 #include <sstream> 13 const int INF=0x3f3f3f3f; 14 typedef long long LL; 15 const int mod=1e9+7; 16 const int maxn=1e5+10; 17 using namespace std; 18 19 struct edge_node 20 { 21 int to; 22 int val; 23 int next; 24 }Edge[maxn*2]; 25 26 int Head[maxn]; 27 int tot; 28 int MAX;//最终为树的直径 29 int sum;//记录当前总花费 30 int st;//出发点 31 int vis[maxn];//标记数组 32 33 void Add_Edge(int u,int v,int val) 34 { 35 Edge[tot].to=v; 36 Edge[tot].val=val; 37 Edge[tot].next=Head[u]; 38 Head[u]=tot++; 39 } 40 41 void DFS(int n,int u)//n是总结点个数,u是出发点 42 { 43 vis[u]=1; 44 for(int i=Head[u];i!=-1;i=Edge[i].next) 45 { 46 int v=Edge[i].to; 47 if(vis[v]==0) 48 { 49 sum+=Edge[i].val; 50 if(sum>MAX) 51 { 52 MAX=sum; 53 st=v; 54 } 55 DFS(n,v); 56 sum-=Edge[i].val; 57 } 58 } 59 vis[u]=0; 60 } 61 62 int main() 63 { 64 int n; 65 scanf("%d",&n); 66 memset(Head,-1,sizeof(Head)); 67 tot=0; 68 for(int i=1;i<=n-1;i++) 69 { 70 int u,v,t; 71 scanf("%d %d %d",&u,&v,&t); 72 Add_Edge(u,v,t); 73 Add_Edge(v,u,t); 74 } 75 st=1;//st为出发点,初始为1 76 for(int i=1;i<=2;i++) 77 { 78 memset(vis,0,sizeof(vis)); 79 sum=0; 80 MAX=0; 81 DFS(n,st); 82 } 83 int ans=MAX*10+((1+MAX)*MAX)/2;//求出要求的答案 84 printf("%d ",ans); 85 return 0; 86 }
-